// 通用系统管理脚手架 (sysmgr) 数据模型 // 约定:表名 sys_ 前缀;列 snake_case(模型 camelCase + @map);业务键关联(角色/资源/组织/字典/租户用 code,用户用 id)。 generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") } /// 租户 model Tenant { id String @id @default(uuid(7)) @db.VarChar(36) code String @unique @db.VarChar(64) name String @db.VarChar(128) status String @default("enabled") @db.VarChar(16) remark String? @db.VarChar(255) brandName String? @map("brand_name") @db.VarChar(64) logoUrl String? @map("logo_url") @db.VarChar(255) themeColor String? @map("theme_color") @db.VarChar(16) copyright String? @db.VarChar(255) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") @@map("sys_tenant") } /// 用户 model User { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) username String @db.VarChar(64) passwordHash String @map("password_hash") @db.VarChar(255) nickname String? @db.VarChar(64) email String? @db.VarChar(128) phone String? @db.VarChar(32) avatar String? @db.VarChar(255) status String @default("enabled") @db.VarChar(16) tokenVersion Int @default(0) @map("token_version") lockedAt DateTime? @map("locked_at") lockReason String? @map("lock_reason") @db.VarChar(255) mustChangePassword Boolean @default(false) @map("must_change_password") orgCode String? @map("org_code") @db.VarChar(64) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@unique([tenantCode, username]) @@index([tenantCode]) @@index([orgCode]) @@map("sys_user") } /// 角色 model Role { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) code String @db.VarChar(64) name String @db.VarChar(64) dataScope String @default("all") @map("data_scope") @db.VarChar(16) status String @default("enabled") @db.VarChar(16) remark String? @db.VarChar(255) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@unique([tenantCode, code]) @@index([tenantCode]) @@map("sys_role") } /// 资源(菜单/按钮/接口) model Resource { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) parentCode String? @map("parent_code") @db.VarChar(64) type String @db.VarChar(16) code String @db.VarChar(128) name String @db.VarChar(64) path String? @db.VarChar(255) component String? @db.VarChar(255) method String? @db.VarChar(8) apiPath String? @map("api_path") @db.VarChar(255) icon String? @db.VarChar(64) sort Int @default(0) status String @default("enabled") @db.VarChar(16) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@unique([tenantCode, code]) @@index([tenantCode]) @@index([parentCode]) @@map("sys_resource") } /// 组织 model Org { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) parentCode String? @map("parent_code") @db.VarChar(64) code String @db.VarChar(64) name String @db.VarChar(64) leader String? @db.VarChar(64) sort Int @default(0) status String @default("enabled") @db.VarChar(16) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@unique([tenantCode, code]) @@index([tenantCode]) @@index([parentCode]) @@map("sys_org") } /// 字典类型 model DictType { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) code String @db.VarChar(64) name String @db.VarChar(64) status String @default("enabled") @db.VarChar(16) builtIn Boolean @default(false) @map("built_in") remark String? @db.VarChar(255) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@unique([tenantCode, code]) @@index([tenantCode]) @@map("sys_dict_type") } /// 字典项 model DictItem { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) dictTypeCode String @map("dict_type_code") @db.VarChar(64) label String @db.VarChar(64) value String @db.VarChar(64) sort Int @default(0) status String @default("enabled") @db.VarChar(16) builtIn Boolean @default(false) @map("built_in") colorType String? @map("color_type") @db.VarChar(16) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@unique([tenantCode, dictTypeCode, value]) @@index([tenantCode, dictTypeCode]) @@map("sys_dict_item") } /// 参数配置 model Config { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) key String @db.VarChar(128) value String? @db.Text remark String? @db.VarChar(255) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@unique([tenantCode, key]) @@map("sys_config") } /// 操作日志(只增,硬删) model AuditLog { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) userId String? @map("user_id") @db.VarChar(36) username String? @db.VarChar(64) module String? @db.VarChar(64) action String? @db.VarChar(64) method String? @db.VarChar(8) path String? @db.VarChar(255) params String? @db.Text result String? @db.Text status String? @db.VarChar(16) errorMessage String? @map("error_message") @db.Text ip String? @db.VarChar(64) userAgent String? @map("user_agent") @db.VarChar(255) durationMs Int? @map("duration_ms") createdAt DateTime @default(now()) @map("created_at") @@index([tenantCode, createdAt]) @@map("sys_audit_log") } /// 登录日志(只增,硬删) model LoginLog { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) username String? @db.VarChar(64) ip String? @db.VarChar(64) userAgent String? @map("user_agent") @db.VarChar(255) status String @default("success") @db.VarChar(16) message String? @db.VarChar(255) createdAt DateTime @default(now()) @map("created_at") @@index([tenantCode, createdAt]) @@map("sys_login_log") } /// 刷新令牌(会话载体,硬删) model RefreshToken { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) userId String @map("user_id") @db.VarChar(36) sid String? @db.VarChar(36) jti String @unique @db.VarChar(64) tokenHash String @map("token_hash") @db.VarChar(255) ip String? @db.VarChar(64) userAgent String? @map("user_agent") @db.VarChar(255) loginAt DateTime @default(now()) @map("login_at") expireAt DateTime @map("expire_at") revokedAt DateTime? @map("revoked_at") createdAt DateTime @default(now()) @map("created_at") @@index([tenantCode, userId]) @@index([sid]) @@map("sys_refresh_token") } /// 通知/公告 model Notice { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) title String @db.VarChar(128) content String @db.Text status String @default("enabled") @db.VarChar(16) createdBy String? @map("created_by") @db.VarChar(36) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@index([tenantCode]) @@map("sys_notice") } /// 通知已读追踪 model NoticeRead { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) noticeId String @map("notice_id") @db.VarChar(36) userId String @map("user_id") @db.VarChar(36) readAt DateTime @default(now()) @map("read_at") @@unique([tenantCode, noticeId, userId]) @@index([tenantCode, userId]) @@map("sys_notice_read") } /// 用户-角色关联 model UserRole { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) userId String @map("user_id") @db.VarChar(36) roleCode String @map("role_code") @db.VarChar(64) @@unique([tenantCode, userId, roleCode]) @@index([tenantCode, userId]) @@map("sys_user_role") } /// 角色-资源关联 model RoleResource { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) roleCode String @map("role_code") @db.VarChar(64) resourceCode String @map("resource_code") @db.VarChar(128) @@unique([tenantCode, roleCode, resourceCode]) @@index([tenantCode, roleCode]) @@map("sys_role_resource") } /// 角色-组织关联(数据权限「自定义」) model RoleOrg { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) roleCode String @map("role_code") @db.VarChar(64) orgCode String @map("org_code") @db.VarChar(64) @@unique([tenantCode, roleCode, orgCode]) @@map("sys_role_org") } /// 机构(=租户的业务信息,1:1 于 Tenant,code 与 tenant.code 同值) model Agency { code String @id @db.VarChar(64) orgName String @map("org_name") @db.VarChar(100) orgType String @map("org_type") @db.VarChar(20) creditCode String @map("credit_code") @db.VarChar(18) locCode String @map("loc_code") @db.VarChar(12) locName String @map("loc_name") @db.VarChar(50) svcSource String @map("svc_source") @db.VarChar(10) licenseNo String? @map("license_no") @db.VarChar(50) address String @map("address") @db.VarChar(200) contactName String @map("contact_name") @db.VarChar(30) contactPhone String @map("contact_phone") @db.VarChar(15) bedCount Int? @map("bed_count") signDate DateTime? @map("sign_date") @db.Date createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@map("ltc_agency") } /// 人员(护理员/医护/组长,账号在 User,staff.user_id 关联 user.id) model Staff { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) userId String? @unique @map("user_id") @db.VarChar(36) name String @db.VarChar(30) idCardNo String @map("id_card_no") @db.VarChar(255) personCode String? @map("person_code") @db.VarChar(20) phone String @db.VarChar(15) jobType String @map("job_type") @db.VarChar(20) workType String @map("work_type") @db.VarChar(10) entryDate DateTime? @map("entry_date") @db.Date leaveDate DateTime? @map("leave_date") @db.Date employStatus String @map("employ_status") @db.VarChar(10) certType String? @map("cert_type") @db.VarChar(20) certNo String? @map("cert_no") @db.VarChar(50) certLevel String? @map("cert_level") @db.VarChar(20) certExpire DateTime? @map("cert_expire") @db.Date certStatus String? @map("cert_status") @db.VarChar(20) certVerifyUrl String? @map("cert_verify_url") @db.VarChar(200) groupLeaderId String? @map("group_leader_id") @db.VarChar(36) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@index([tenantCode, name]) @@map("ltc_staff") } /// 国家基准库 L1(全局,36 项) model SvcNational { id String @id @default(uuid(7)) @db.VarChar(36) natCode String @unique @map("nat_code") @db.VarChar(20) natName String @map("nat_name") @db.VarChar(100) natCategory String @map("nat_category") @db.VarChar(20) natSubCategory String? @map("nat_sub_category") @db.VarChar(50) recommendStaff String? @map("recommend_staff") @db.VarChar(50) recommendDuration String? @map("recommend_duration") @db.VarChar(50) isMedical Boolean @default(false) @map("is_medical") version Int @default(1) @@map("svc_national") } /// 属地目录 L2(全局,昆明 45 项 / 州市引用 L1) model SvcLocal { id String @id @default(uuid(7)) @db.VarChar(36) locCode String @map("loc_code") @db.VarChar(12) localItemName String @map("local_item_name") @db.VarChar(100) localCategory String? @map("local_category") @db.VarChar(20) svcTime String? @map("svc_time") @db.VarChar(50) minFreq String? @map("min_freq") @db.VarChar(50) staffQual String? @map("staff_qual") @db.VarChar(50) isMedical Boolean @default(false) @map("is_medical") sourceDoc String? @map("source_doc") @db.VarChar(200) mapStatus String @default("mapped") @map("map_status") @db.VarChar(20) @@index([locCode]) @@map("svc_local") } /// 属地↔国家映射 L3(全局,机构不可见) model SvcMapping { id String @id @default(uuid(7)) @db.VarChar(36) locId String @map("loc_id") @db.VarChar(36) natId String? @map("nat_id") @db.VarChar(36) mapType String @map("map_type") @db.VarChar(20) mapNote String? @map("map_note") @db.VarChar(200) status String @default("confirmed") @db.VarChar(20) @@index([locId]) @@map("svc_mapping") } /// 机构项目库 L4(租户级:机构勾选+配价) model SvcOrg { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) srcType String @map("src_type") @db.VarChar(10) srcId String @map("src_id") @db.VarChar(36) isEnabled Boolean @default(true) @map("is_enabled") price String? @map("price") @db.VarChar(50) priceEffective DateTime? @map("price_effective") isNewNational Boolean @default(false) @map("is_new_national") createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@index([tenantCode, srcType]) @@map("svc_org") } /// 统筹区配置(全局) model LocConfig { locCode String @id @map("loc_code") @db.VarChar(12) locName String @map("loc_name") @db.VarChar(50) svcSource String @map("svc_source") @db.VarChar(10) itemCountRule String? @map("item_count_rule") @db.VarChar(100) @@map("loc_config") } /// 老人档案 model Elder { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) locCode String @map("loc_code") @db.VarChar(12) prevLocCode String? @map("prev_loc_code") @db.VarChar(12) transferConfirmAt DateTime? @map("transfer_confirm_at") name String @db.VarChar(30) gender String @db.Char(1) birthDate DateTime @map("birth_date") @db.Date idCardNo String @map("id_card_no") @db.VarChar(255) phone String? @db.VarChar(15) address String @db.VarChar(200) guardianName String? @map("guardian_name") @db.VarChar(30) guardianPhone String? @map("guardian_phone") @db.VarChar(15) insurNo String @map("insur_no") @db.VarChar(30) insurType String @map("insur_type") @db.VarChar(10) insurYears Int? @map("insur_years") insurVerifyStatus String? @map("insur_verify_status") @db.VarChar(20) insurVerifyDate DateTime? @map("insur_verify_date") @db.Date assessLevel String? @map("assess_level") @db.VarChar(20) careLevel String? @map("care_level") @db.VarChar(20) assessDate DateTime? @map("assess_date") @db.Date assessOrg String? @map("assess_org") @db.VarChar(100) assessEvidenceFile String? @map("assess_evidence_file") @db.VarChar(255) benefitStart DateTime? @map("benefit_start") @db.Date benefitEnd DateTime? @map("benefit_end") @db.Date treatStatus String @default("pending_file") @map("treat_status") @db.VarChar(20) statusSource String @default("manual") @map("status_source") @db.VarChar(10) statusChangeDate DateTime? @map("status_change_date") @db.Date hospStart DateTime? @map("hosp_start") @db.Date hospEnd DateTime? @map("hosp_end") @db.Date photoTierOverride Json? @map("photo_tier_override") needAssess Json? @map("need_assess") note String? @db.Text bizLine String @default("ltci") @map("biz_line") @db.VarChar(20) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@unique([tenantCode, idCardNo]) @@index([tenantCode, name]) @@map("ltc_elder") } /// 待遇状态变更日志 model ElderStatusLog { id String @id @default(uuid(7)) @db.VarChar(36) elderId String @map("elder_id") @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) fromStatus String @map("from_status") @db.VarChar(20) toStatus String @map("to_status") @db.VarChar(20) changeReason String @map("change_reason") @db.VarChar(200) source String @default("manual") @db.VarChar(10) operatorId String @map("operator_id") @db.VarChar(36) evidenceFile String? @map("evidence_file") @db.VarChar(255) changedAt DateTime @default(now()) @map("changed_at") @@index([elderId]) @@map("ltc_elder_status_log") } /// 服务计划头 model Plan { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) elderId String @map("elder_id") @db.VarChar(36) planPeriodStart DateTime @map("plan_period_start") @db.Date planPeriodEnd DateTime @map("plan_period_end") @db.Date careLevel String @map("care_level") @db.VarChar(20) careMode String @map("care_mode") @db.VarChar(20) itemCount Int @default(0) @map("item_count") itemCountRule String? @map("item_count_rule") @db.VarChar(100) extraItemCount Int @default(0) @map("extra_item_count") weekFreq Int? @map("week_freq") monthHours Int? @map("month_hours") planStatus String @default("draft") @map("plan_status") @db.VarChar(20) confirmElder Boolean @default(false) @map("confirm_elder") confirmGuardian Boolean @default(false) @map("confirm_guardian") confirmTime DateTime? @map("confirm_time") planBasis Json? @map("plan_basis") changeFromPlanId String? @map("change_from_plan_id") @db.VarChar(36) bizLine String @default("ltci") @map("biz_line") @db.VarChar(20) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@index([tenantCode, elderId]) @@map("svc_plan") } /// 服务计划项 model PlanItem { id String @id @default(uuid(7)) @db.VarChar(36) planId String @map("plan_id") @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) svcId String @map("svc_id") @db.VarChar(36) svcNameSnapshot String @map("svc_name_snapshot") @db.VarChar(100) svcCodeSnapshot String? @map("svc_code_snapshot") @db.VarChar(20) freqType String? @map("freq_type") @db.VarChar(20) freqValue Int? @map("freq_value") durationMin Int? @map("duration_min") photoTier String @default("free") @map("photo_tier") @db.VarChar(10) cautionNote String? @map("caution_note") @db.Text isMedical Boolean @default(false) @map("is_medical") needCert Boolean @default(false) @map("need_cert") @@index([planId]) @@map("svc_plan_item") } /// 工单 model Order { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) elderId String @map("elder_id") @db.VarChar(36) planId String @map("plan_id") @db.VarChar(36) serviceDate DateTime @map("service_date") @db.Date timeSlotStart DateTime @map("time_slot_start") timeSlotEnd DateTime @map("time_slot_end") assigneeId String? @map("assignee_id") @db.VarChar(36) assignTime DateTime? @map("assign_time") assignMode String? @map("assign_mode") @db.VarChar(20) orderStatus String @default("to_assign") @map("order_status") @db.VarChar(20) itemList Json @map("item_list") needPhoto Boolean @default(false) @map("need_photo") cancelReason String? @map("cancel_reason") @db.VarChar(200) rescheduleLog Json? @map("reschedule_log") qualificationCheck String? @map("qualification_check") @db.VarChar(20) billable Boolean @default(true) @map("billable") priceSnapshot Json? @map("price_snapshot") settlePeriod String? @map("settle_period") @db.VarChar(20) notMetReason String? @map("not_met_reason") @db.VarChar(50) notMetAt DateTime? @map("not_met_at") bizLine String @default("ltci") @map("biz_line") @db.VarChar(20) createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@index([tenantCode, assigneeId, serviceDate]) @@index([tenantCode, elderId]) @@map("svc_order") } /// 老人个人项目库 model ElderSvc { id String @id @default(uuid(7)) @db.VarChar(36) tenantCode String @map("tenant_code") @db.VarChar(64) elderId String @map("elder_id") @db.VarChar(36) svcId String @map("svc_id") @db.VarChar(36) svcNameSnapshot String @map("svc_name_snapshot") @db.VarChar(100) svcCodeSnapshot String? @map("svc_code_snapshot") @db.VarChar(20) careMode String @map("care_mode") @db.VarChar(20) isActive Boolean @default(true) @map("is_active") createdAt DateTime @default(now()) @map("created_at") createdBy String? @map("created_by") @db.VarChar(36) updatedAt DateTime @updatedAt @map("updated_at") deletedAt DateTime? @map("deleted_at") @@index([tenantCode, elderId]) @@map("ltc_elder_svc") }