import { eq } from "drizzle-orm"; import { getDatabase } from "@/modules/core/server/db"; import { admissions, beds, buildings, campuses, careTasks, chronicConditions, elders, floors, healthAnomalyReviews, healthProfiles, rooms, systemIncidents, vitalRecords, } from "@/modules/core/server/schema"; type SeedRoom = { buildingName: string; campusName: string; code: string; floorLevel: number; floorName: string; name: string; capacity: number; }; type SeedBed = { code: string; notes: string; roomCode: string; status: "available" | "occupied" | "maintenance" | "disabled"; }; type SeedElder = { age: number; careLevel: "self-care" | "semi-assisted" | "assisted" | "intensive"; gender: "male" | "female" | "other"; medicalNotes: string; name: string; phone: string; primaryContact: string; status: "active" | "pending" | "discharged"; }; type SeedAdmission = { bedCode: string; elderName: string; notes: string; status: "active" | "transferred" | "discharged"; }; type SeedHealthProfile = { allergyNotes: string; careRestrictions: string; elderName: string; emergencyNotes: string; medicalHistory: string; medicationNotes: string; }; type SeedVitalRecord = { bloodGlucoseTenths?: number; diastolicBp?: number; elderName: string; heartRate?: number; notes: string; recordedHoursAgo: number; source: "manual" | "device" | "import"; spo2?: number; systolicBp?: number; temperatureTenths?: number; weightTenths?: number; }; type SeedChronicCondition = { elderName: string; followUpNotes: string; name: string; status: "active" | "controlled" | "resolved"; treatmentNotes: string; }; type SeedHealthReview = { description: string; elderName: string; resolutionNotes: string; severity: "info" | "warning" | "critical"; status: "pending" | "reviewed" | "resolved"; title: string; vitalIndex: number; }; type SeedCareTask = { assigneeLabel: string; careType: "daily_care" | "meal" | "medication" | "rehab" | "inspection" | "cleaning" | "other"; completedHoursAgo?: number; elderName: string; executionNotes: string; priority: "low" | "normal" | "high" | "urgent"; scheduledHoursOffset: number; status: "pending" | "in_progress" | "completed" | "cancelled"; title: string; }; type SeedSystemIncident = { acknowledgedHoursAgo?: number; createdHoursAgo: number; description: string; resolvedHoursAgo?: number; severity: "info" | "warning" | "critical"; source: string; status: "open" | "acknowledged" | "resolved" | "closed"; title: string; }; const DEFAULT_ROOMS: SeedRoom[] = [ { campusName: "主院区", buildingName: "护理楼", floorName: "一层", floorLevel: 1, code: "A101", name: "阳光房", capacity: 2 }, { campusName: "主院区", buildingName: "护理楼", floorName: "一层", floorLevel: 1, code: "A102", name: "康养房", capacity: 2 }, { campusName: "主院区", buildingName: "护理楼", floorName: "二层", floorLevel: 2, code: "A201", name: "记忆照护房", capacity: 2 }, { campusName: "主院区", buildingName: "护理楼", floorName: "二层", floorLevel: 2, code: "A202", name: "重点照护房", capacity: 2 }, { campusName: "主院区", buildingName: "护理楼", floorName: "三层", floorLevel: 3, code: "A301", name: "失能照护房", capacity: 2 }, { campusName: "主院区", buildingName: "护理楼", floorName: "三层", floorLevel: 3, code: "A302", name: "安宁照护房", capacity: 2 }, { campusName: "主院区", buildingName: "康复楼", floorName: "一层", floorLevel: 1, code: "R101", name: "康复观察房", capacity: 2 }, { campusName: "主院区", buildingName: "康复楼", floorName: "一层", floorLevel: 1, code: "R102", name: "短住评估房", capacity: 2 }, { campusName: "主院区", buildingName: "康复楼", floorName: "二层", floorLevel: 2, code: "R201", name: "术后康复房", capacity: 2 }, { campusName: "主院区", buildingName: "康复楼", floorName: "二层", floorLevel: 2, code: "R202", name: "认知训练房", capacity: 2 }, { campusName: "北苑院区", buildingName: "颐养楼", floorName: "一层", floorLevel: 1, code: "B101", name: "自理房", capacity: 2 }, { campusName: "北苑院区", buildingName: "颐养楼", floorName: "二层", floorLevel: 2, code: "B201", name: "亲情套房", capacity: 2 }, { campusName: "北苑院区", buildingName: "颐养楼", floorName: "二层", floorLevel: 2, code: "B202", name: "陪护套房", capacity: 2 }, { campusName: "南苑院区", buildingName: "医养楼", floorName: "一层", floorLevel: 1, code: "S101", name: "医养观察房", capacity: 2 }, { campusName: "南苑院区", buildingName: "医养楼", floorName: "一层", floorLevel: 1, code: "S102", name: "短期托养房", capacity: 2 }, ]; const DEFAULT_BEDS: SeedBed[] = [ { code: "A101-1", roomCode: "A101", status: "occupied", notes: "靠窗,已完成入住评估" }, { code: "A101-2", roomCode: "A101", status: "available", notes: "可安排半护理老人入住" }, { code: "A102-1", roomCode: "A102", status: "occupied", notes: "夜间巡护重点关注" }, { code: "A102-2", roomCode: "A102", status: "maintenance", notes: "床头呼叫器检修中" }, { code: "A201-1", roomCode: "A201", status: "occupied", notes: "记忆照护专区" }, { code: "A201-2", roomCode: "A201", status: "available", notes: "靠近护理站" }, { code: "A202-1", roomCode: "A202", status: "occupied", notes: "压疮风险重点巡查" }, { code: "A202-2", roomCode: "A202", status: "disabled", notes: "待更换护栏" }, { code: "A301-1", roomCode: "A301", status: "occupied", notes: "失能照护,配置防跌倒垫" }, { code: "A301-2", roomCode: "A301", status: "available", notes: "鼻饲护理设备已消毒待用" }, { code: "A302-1", roomCode: "A302", status: "available", notes: "家属陪伴预约优先" }, { code: "A302-2", roomCode: "A302", status: "maintenance", notes: "氧气接口保养" }, { code: "R101-1", roomCode: "R101", status: "occupied", notes: "康复训练后休息床位" }, { code: "R101-2", roomCode: "R101", status: "available", notes: "临时观察床位" }, { code: "R102-1", roomCode: "R102", status: "available", notes: "短住评估床位" }, { code: "R102-2", roomCode: "R102", status: "available", notes: "短住评估床位" }, { code: "R201-1", roomCode: "R201", status: "occupied", notes: "术后康复第 2 周" }, { code: "R201-2", roomCode: "R201", status: "available", notes: "康复床位候补" }, { code: "R202-1", roomCode: "R202", status: "occupied", notes: "认知训练老人长期床位" }, { code: "R202-2", roomCode: "R202", status: "available", notes: "靠近活动室" }, { code: "B101-1", roomCode: "B101", status: "occupied", notes: "自理老人长期床位" }, { code: "B101-2", roomCode: "B101", status: "available", notes: "低照护需求床位" }, { code: "B201-1", roomCode: "B201", status: "available", notes: "亲属探访便利" }, { code: "B201-2", roomCode: "B201", status: "available", notes: "亲情套房备用床" }, { code: "B202-1", roomCode: "B202", status: "occupied", notes: "陪护套房,家属每周探访" }, { code: "B202-2", roomCode: "B202", status: "available", notes: "可接收短住老人" }, { code: "S101-1", roomCode: "S101", status: "occupied", notes: "医养观察,夜间吸氧" }, { code: "S101-2", roomCode: "S101", status: "disabled", notes: "待更换床垫" }, { code: "S102-1", roomCode: "S102", status: "available", notes: "短期托养床位" }, { code: "S102-2", roomCode: "S102", status: "available", notes: "短期托养床位" }, ]; const DEFAULT_ELDERS: SeedElder[] = [ { name: "王桂兰", gender: "female", age: 82, careLevel: "intensive", status: "active", primaryContact: "张敏", phone: "13800000001", medicalNotes: "高血压,需晨晚血压记录。", }, { name: "李建国", gender: "male", age: 76, careLevel: "semi-assisted", status: "active", primaryContact: "李明", phone: "13800000002", medicalNotes: "餐后散步陪同,关注睡眠情况。", }, { name: "周玉珍", gender: "female", age: 88, careLevel: "assisted", status: "active", primaryContact: "周强", phone: "13800000003", medicalNotes: "糖尿病饮食,餐前血糖提醒。", }, { name: "赵国华", gender: "male", age: 91, careLevel: "intensive", status: "active", primaryContact: "赵琳", phone: "13800000004", medicalNotes: "夜间翻身,两小时巡房。", }, { name: "孙秀梅", gender: "female", age: 73, careLevel: "semi-assisted", status: "active", primaryContact: "孙磊", phone: "13800000005", medicalNotes: "膝关节康复训练,每日下午一次。", }, { name: "刘长青", gender: "male", age: 68, careLevel: "self-care", status: "active", primaryContact: "刘洋", phone: "13800000006", medicalNotes: "自理,需定期复查用药。", }, { name: "陈秀英", gender: "female", age: 69, careLevel: "self-care", status: "pending", primaryContact: "陈佳", phone: "13800000007", medicalNotes: "待完成入住评估。", }, { name: "何德明", gender: "male", age: 84, careLevel: "assisted", status: "pending", primaryContact: "何静", phone: "13800000008", medicalNotes: "家属已提交体检资料,等待床位确认。", }, { name: "吴佩兰", gender: "female", age: 79, careLevel: "semi-assisted", status: "discharged", primaryContact: "吴昊", phone: "13800000009", medicalNotes: "已退住,保留历史档案。", }, { name: "郑文远", gender: "male", age: 72, careLevel: "self-care", status: "discharged", primaryContact: "郑洁", phone: "13800000010", medicalNotes: "短住康复结束后退住。", }, { name: "马淑芬", gender: "female", age: 86, careLevel: "intensive", status: "active", primaryContact: "马晨", phone: "13800000011", medicalNotes: "吞咽困难,晚餐需软食并观察呛咳。", }, { name: "胡志强", gender: "male", age: 80, careLevel: "assisted", status: "active", primaryContact: "胡悦", phone: "13800000012", medicalNotes: "术后康复,需记录每日步行距离。", }, { name: "高兰英", gender: "female", age: 77, careLevel: "semi-assisted", status: "active", primaryContact: "高磊", phone: "13800000013", medicalNotes: "轻度认知障碍,活动后需陪同返回房间。", }, { name: "钱松柏", gender: "male", age: 89, careLevel: "intensive", status: "active", primaryContact: "钱宁", phone: "13800000014", medicalNotes: "慢阻肺,夜间吸氧,重点关注血氧。", }, { name: "林玉琴", gender: "female", age: 71, careLevel: "self-care", status: "active", primaryContact: "林涛", phone: "13800000015", medicalNotes: "短住托养,需协助完成初次健康档案。", }, { name: "曹文海", gender: "male", age: 83, careLevel: "assisted", status: "pending", primaryContact: "曹颖", phone: "13800000016", medicalNotes: "已预约下周入住,等待家属确认床位。", }, { name: "罗海燕", gender: "female", age: 75, careLevel: "semi-assisted", status: "pending", primaryContact: "罗杰", phone: "13800000017", medicalNotes: "需补充近期体检报告。", }, { name: "邓启明", gender: "male", age: 70, careLevel: "self-care", status: "discharged", primaryContact: "邓可", phone: "13800000018", medicalNotes: "试住结束后转家庭照护。", }, ]; const DEFAULT_ADMISSIONS: SeedAdmission[] = [ { elderName: "王桂兰", bedCode: "A101-1", status: "active", notes: "默认工作区入住记录" }, { elderName: "李建国", bedCode: "A102-1", status: "active", notes: "默认工作区入住记录" }, { elderName: "周玉珍", bedCode: "A201-1", status: "active", notes: "记忆照护专区入住" }, { elderName: "赵国华", bedCode: "A202-1", status: "active", notes: "重点照护入住" }, { elderName: "孙秀梅", bedCode: "R101-1", status: "active", notes: "康复观察入住" }, { elderName: "刘长青", bedCode: "B101-1", status: "active", notes: "自理区入住" }, { elderName: "马淑芬", bedCode: "A301-1", status: "active", notes: "失能照护入住" }, { elderName: "胡志强", bedCode: "R201-1", status: "active", notes: "术后康复入住" }, { elderName: "高兰英", bedCode: "R202-1", status: "active", notes: "认知训练入住" }, { elderName: "钱松柏", bedCode: "S101-1", status: "active", notes: "医养观察入住" }, { elderName: "林玉琴", bedCode: "B202-1", status: "active", notes: "短住托养入住" }, { elderName: "吴佩兰", bedCode: "B201-1", status: "discharged", notes: "历史退住记录" }, { elderName: "邓启明", bedCode: "A301-2", status: "discharged", notes: "试住退住记录" }, ]; const DEFAULT_HEALTH_PROFILES: SeedHealthProfile[] = [ { elderName: "王桂兰", allergyNotes: "青霉素过敏", medicalHistory: "高血压十余年,偶发胸闷。", medicationNotes: "晨服降压药,晚间复核血压。", careRestrictions: "低盐饮食,避免剧烈活动。", emergencyNotes: "胸闷或血压持续升高时立即联系医生。", }, { elderName: "周玉珍", allergyNotes: "无明确药物过敏史", medicalHistory: "2 型糖尿病,轻度认知障碍。", medicationNotes: "餐前血糖监测,按医嘱用药。", careRestrictions: "控糖饮食,夜间加强巡护。", emergencyNotes: "低血糖症状时立即补糖并记录。", }, { elderName: "赵国华", allergyNotes: "海鲜过敏", medicalHistory: "脑梗后遗症,长期卧床风险。", medicationNotes: "抗凝药按时服用。", careRestrictions: "两小时翻身,防跌倒,防压疮。", emergencyNotes: "意识异常或血氧下降时立即启动应急流程。", }, { elderName: "刘长青", allergyNotes: "", medicalHistory: "冠心病随访。", medicationNotes: "自主管理用药,护理员每日提醒。", careRestrictions: "避免爬楼和长时间站立。", emergencyNotes: "胸痛需立即报告。", }, { elderName: "马淑芬", allergyNotes: "头孢类药物过敏", medicalHistory: "脑梗后吞咽功能下降,近期体重下降。", medicationNotes: "晚间营养补充剂,服药后观察吞咽。", careRestrictions: "软食,进食时保持坐位,餐后半小时内不平卧。", emergencyNotes: "呛咳、紫绀或呼吸急促时立即通知医生。", }, { elderName: "胡志强", allergyNotes: "", medicalHistory: "髋关节术后康复中。", medicationNotes: "按医嘱服用止痛药和抗凝药。", careRestrictions: "转移位需双人协助,禁止独自上下楼。", emergencyNotes: "伤口渗血或疼痛加重时联系康复医生。", }, { elderName: "高兰英", allergyNotes: "无明确药物过敏史", medicalHistory: "轻度认知障碍,夜间偶发迷路。", medicationNotes: "睡前药物由护理员核对。", careRestrictions: "外出活动需佩戴定位牌。", emergencyNotes: "离开活动区超过 10 分钟未返回时启动寻人流程。", }, { elderName: "钱松柏", allergyNotes: "", medicalHistory: "慢阻肺,长期吸入治疗。", medicationNotes: "吸入剂每日两次,夜间低流量吸氧。", careRestrictions: "避免受凉和烟味刺激。", emergencyNotes: "血氧低于 90 或呼吸困难时立即启动应急流程。", }, { elderName: "林玉琴", allergyNotes: "无", medicalHistory: "短住托养,既往骨质疏松。", medicationNotes: "钙剂和维生素 D 每日提醒。", careRestrictions: "浴室需防滑协助。", emergencyNotes: "跌倒后即刻评估并通知家属。", }, ]; const DEFAULT_VITAL_RECORDS: SeedVitalRecord[] = [ { elderName: "王桂兰", recordedHoursAgo: 2, source: "manual", systolicBp: 158, diastolicBp: 96, heartRate: 88, temperatureTenths: 367, spo2: 96, bloodGlucoseTenths: 62, weightTenths: 612, notes: "血压偏高,已安排复测。", }, { elderName: "李建国", recordedHoursAgo: 5, source: "device", systolicBp: 128, diastolicBp: 78, heartRate: 76, temperatureTenths: 365, spo2: 98, notes: "体征平稳。", }, { elderName: "周玉珍", recordedHoursAgo: 7, source: "manual", systolicBp: 134, diastolicBp: 82, heartRate: 80, temperatureTenths: 366, spo2: 97, bloodGlucoseTenths: 118, notes: "餐后血糖偏高,已记录饮食。", }, { elderName: "赵国华", recordedHoursAgo: 12, source: "manual", systolicBp: 146, diastolicBp: 88, heartRate: 92, temperatureTenths: 381, spo2: 91, notes: "体温和血氧异常,需复核。", }, { elderName: "马淑芬", recordedHoursAgo: 3, source: "manual", systolicBp: 142, diastolicBp: 86, heartRate: 96, temperatureTenths: 369, spo2: 94, bloodGlucoseTenths: 73, weightTenths: 486, notes: "晚餐前复测,吞咽情况稳定。", }, { elderName: "胡志强", recordedHoursAgo: 9, source: "device", systolicBp: 124, diastolicBp: 76, heartRate: 82, temperatureTenths: 364, spo2: 98, weightTenths: 705, notes: "康复训练后体征平稳。", }, { elderName: "高兰英", recordedHoursAgo: 15, source: "manual", systolicBp: 136, diastolicBp: 84, heartRate: 78, temperatureTenths: 366, spo2: 97, bloodGlucoseTenths: 65, notes: "夜间巡护记录,情绪平稳。", }, { elderName: "钱松柏", recordedHoursAgo: 1, source: "device", systolicBp: 150, diastolicBp: 88, heartRate: 104, temperatureTenths: 372, spo2: 89, notes: "夜间血氧低,已安排吸氧复核。", }, { elderName: "林玉琴", recordedHoursAgo: 22, source: "import", systolicBp: 118, diastolicBp: 72, heartRate: 70, temperatureTenths: 363, spo2: 99, bloodGlucoseTenths: 58, weightTenths: 552, notes: "入院体检导入记录。", }, { elderName: "王桂兰", recordedHoursAgo: 26, source: "device", systolicBp: 145, diastolicBp: 90, heartRate: 84, temperatureTenths: 366, spo2: 97, notes: "前一日夜间复测,血压较高。", }, { elderName: "周玉珍", recordedHoursAgo: 30, source: "manual", systolicBp: 130, diastolicBp: 80, heartRate: 74, temperatureTenths: 365, spo2: 98, bloodGlucoseTenths: 92, notes: "晨间血糖记录。", }, ]; const DEFAULT_CHRONIC_CONDITIONS: SeedChronicCondition[] = [ { elderName: "王桂兰", name: "高血压", status: "active", treatmentNotes: "规律服药,晨晚血压监测。", followUpNotes: "每周汇总血压趋势。", }, { elderName: "周玉珍", name: "糖尿病", status: "active", treatmentNotes: "控糖饮食,餐前餐后血糖记录。", followUpNotes: "异常血糖进入复核队列。", }, { elderName: "刘长青", name: "冠心病", status: "controlled", treatmentNotes: "按医嘱服药,避免劳累。", followUpNotes: "月度复诊提醒。", }, { elderName: "马淑芬", name: "吞咽功能障碍", status: "active", treatmentNotes: "软食和吞咽训练,餐中观察呛咳。", followUpNotes: "每三天评估进食量和体重。", }, { elderName: "胡志强", name: "髋关节术后康复", status: "active", treatmentNotes: "每日步态训练,逐步增加步行距离。", followUpNotes: "康复师每周复评。", }, { elderName: "高兰英", name: "轻度认知障碍", status: "controlled", treatmentNotes: "认知训练和日常定向提醒。", followUpNotes: "观察夜间离床次数。", }, { elderName: "钱松柏", name: "慢阻肺", status: "active", treatmentNotes: "吸入治疗和低流量吸氧。", followUpNotes: "每日汇总夜间血氧趋势。", }, { elderName: "林玉琴", name: "骨质疏松", status: "controlled", treatmentNotes: "补钙、维生素 D 和防跌倒宣教。", followUpNotes: "短住结束前出具照护建议。", }, { elderName: "吴佩兰", name: "膝关节退行性病变", status: "resolved", treatmentNotes: "历史康复记录归档。", followUpNotes: "退住后无需跟进。", }, ]; const DEFAULT_HEALTH_REVIEWS: SeedHealthReview[] = [ { elderName: "王桂兰", vitalIndex: 0, severity: "warning", status: "pending", title: "血压异常", description: "收缩压和舒张压偏高,需要复测并确认用药。", resolutionNotes: "", }, { elderName: "赵国华", vitalIndex: 3, severity: "critical", status: "pending", title: "血氧和体温异常", description: "血氧低于阈值且体温偏高,需要立即复核。", resolutionNotes: "", }, { elderName: "周玉珍", vitalIndex: 2, severity: "info", status: "reviewed", title: "餐后血糖偏高", description: "餐后血糖高于日常水平。", resolutionNotes: "已调整晚餐主食并安排次日复测。", }, { elderName: "钱松柏", vitalIndex: 7, severity: "critical", status: "pending", title: "夜间血氧低", description: "设备记录血氧低于 90,需要确认吸氧和呼吸状态。", resolutionNotes: "", }, { elderName: "马淑芬", vitalIndex: 4, severity: "warning", status: "reviewed", title: "体重下降观察", description: "近期体重偏低,需要结合进食量继续观察。", resolutionNotes: "已通知营养师调整晚间加餐。", }, { elderName: "王桂兰", vitalIndex: 9, severity: "info", status: "resolved", title: "血压复核完成", description: "前一日夜间血压偏高,今日已复测。", resolutionNotes: "晨间复测仍偏高,转入本日待处理复核。", }, ]; const DEFAULT_CARE_TASKS: SeedCareTask[] = [ { elderName: "王桂兰", title: "晨间协助洗漱与翻身", careType: "daily_care", priority: "normal", status: "pending", scheduledHoursOffset: 1, assigneeLabel: "一号护理组", executionNotes: "", }, { elderName: "孙秀梅", title: "膝关节康复训练陪同", careType: "rehab", priority: "high", status: "in_progress", scheduledHoursOffset: -1, assigneeLabel: "康复护理组", executionNotes: "已完成热身,等待康复师复核动作。", }, { elderName: "周玉珍", title: "餐前血糖记录与助餐", careType: "meal", priority: "normal", status: "completed", scheduledHoursOffset: -4, completedHoursAgo: 3, assigneeLabel: "二号护理组", executionNotes: "餐前血糖已记录,午餐摄入约八成。", }, { elderName: "赵国华", title: "重点照护夜间巡检补记", careType: "inspection", priority: "urgent", status: "pending", scheduledHoursOffset: -2, assigneeLabel: "夜班护理组", executionNotes: "", }, { elderName: "刘长青", title: "用药提醒与胸痛询问", careType: "medication", priority: "high", status: "pending", scheduledHoursOffset: 3, assigneeLabel: "三号护理组", executionNotes: "", }, { elderName: "马淑芬", title: "晚餐软食进食观察", careType: "meal", priority: "urgent", status: "pending", scheduledHoursOffset: 2, assigneeLabel: "重点护理组", executionNotes: "", }, { elderName: "胡志强", title: "步行训练记录", careType: "rehab", priority: "normal", status: "completed", scheduledHoursOffset: -6, completedHoursAgo: 5, assigneeLabel: "康复护理组", executionNotes: "扶行 80 米,未诉明显疼痛。", }, { elderName: "高兰英", title: "活动室返回陪同", careType: "daily_care", priority: "normal", status: "in_progress", scheduledHoursOffset: 0, assigneeLabel: "二号护理组", executionNotes: "已到活动室,等待小组活动结束。", }, { elderName: "钱松柏", title: "夜间吸氧设备检查", careType: "inspection", priority: "urgent", status: "pending", scheduledHoursOffset: -1, assigneeLabel: "夜班护理组", executionNotes: "", }, { elderName: "林玉琴", title: "短住入院宣教", careType: "other", priority: "low", status: "completed", scheduledHoursOffset: -24, completedHoursAgo: 23, assigneeLabel: "接待护理组", executionNotes: "已完成房间设施、防跌倒和呼叫器使用说明。", }, { elderName: "赵国华", title: "床单位清洁消毒", careType: "cleaning", priority: "normal", status: "cancelled", scheduledHoursOffset: -8, assigneeLabel: "保洁协同组", executionNotes: "因临时复查延期,已改派夜班完成。", }, ]; const DEFAULT_SYSTEM_INCIDENTS: SeedSystemIncident[] = [ { severity: "warning", status: "open", title: "床头呼叫器待检修", description: "A102-2 床位呼叫器处于检修状态,完成后可恢复使用。", source: "默认工作区初始化", createdHoursAgo: 2, }, { severity: "info", status: "acknowledged", title: "本周护理评估待完成", description: "陈秀英、何德明等待入住评估,可在老人档案和床位工作区继续处理。", source: "默认工作区初始化", createdHoursAgo: 6, acknowledgedHoursAgo: 5, }, { severity: "critical", status: "resolved", title: "夜间巡房异常已处理", description: "重点照护房夜间巡房提醒已恢复,保留事件用于状态页验证。", source: "默认工作区初始化", createdHoursAgo: 14, acknowledgedHoursAgo: 13, resolvedHoursAgo: 11, }, { severity: "critical", status: "open", title: "S101 医养观察房血氧告警", description: "钱松柏夜间血氧持续低于阈值,需要护理组和医生复核。", source: "生命体征设备", createdHoursAgo: 1, }, { severity: "warning", status: "acknowledged", title: "A302 氧气接口保养延期", description: "A302-2 氧气接口保养未按计划完成,床位暂不安排入住。", source: "设备巡检", createdHoursAgo: 20, acknowledgedHoursAgo: 18, }, { severity: "info", status: "closed", title: "短住托养资料归档完成", description: "林玉琴短住托养资料已录入并完成家属确认。", source: "接待护理组", createdHoursAgo: 28, acknowledgedHoursAgo: 27, resolvedHoursAgo: 24, }, ]; function hasRows(rows: unknown[]): boolean { return rows.length > 0; } export async function seedDefaultWorkspaceData(organizationId: string): Promise { const database = getDatabase(); const [existingRooms, existingBeds, existingElders, existingAdmissions] = await Promise.all([ database.select({ id: rooms.id }).from(rooms).where(eq(rooms.organizationId, organizationId)).limit(1), database.select({ id: beds.id }).from(beds).where(eq(beds.organizationId, organizationId)).limit(1), database.select({ id: elders.id }).from(elders).where(eq(elders.organizationId, organizationId)).limit(1), database.select({ id: admissions.id }).from(admissions).where(eq(admissions.organizationId, organizationId)).limit(1), ]); if ([existingRooms, existingBeds, existingElders, existingAdmissions].some(hasRows)) { return; } await database.transaction(async (transaction) => { const uniqueCampusNames = Array.from(new Set(DEFAULT_ROOMS.map((room) => room.campusName))); const campusRows = await transaction .insert(campuses) .values( uniqueCampusNames.map((name) => ({ organizationId, name, address: `${name}养老服务院区`, })), ) .returning(); if (campusRows.length !== uniqueCampusNames.length) { throw new Error("默认院区初始化失败"); } const campusIdByName = new Map(campusRows.map((campus) => [campus.name, campus.id])); const uniqueBuildings = Array.from( new Map(DEFAULT_ROOMS.map((room) => [`${room.campusName}/${room.buildingName}`, room])).values(), ); const buildingRows = await transaction .insert(buildings) .values( uniqueBuildings.map((building) => { const campusId = campusIdByName.get(building.campusName); if (!campusId) { throw new Error("默认楼栋初始化失败"); } return { organizationId, campusId, name: building.buildingName, }; }), ) .returning(); if (buildingRows.length !== uniqueBuildings.length) { throw new Error("默认楼栋初始化失败"); } const buildingIdByKey = new Map( buildingRows.map((building, index) => { const source = uniqueBuildings[index]; if (!source) { throw new Error("默认楼栋初始化失败"); } return [`${source.campusName}/${source.buildingName}`, building.id]; }), ); const uniqueFloors = Array.from( new Map( DEFAULT_ROOMS.map((room) => [ `${room.campusName}/${room.buildingName}/${room.floorLevel}`, room, ]), ).values(), ); const floorRows = await transaction .insert(floors) .values( uniqueFloors.map((floor) => { const buildingId = buildingIdByKey.get(`${floor.campusName}/${floor.buildingName}`); if (!buildingId) { throw new Error("默认楼层初始化失败"); } return { organizationId, buildingId, name: floor.floorName, level: floor.floorLevel, }; }), ) .returning(); if (floorRows.length !== uniqueFloors.length) { throw new Error("默认楼层初始化失败"); } const floorIdByKey = new Map( floorRows.map((floor, index) => { const source = uniqueFloors[index]; if (!source) { throw new Error("默认楼层初始化失败"); } return [`${source.campusName}/${source.buildingName}/${source.floorLevel}`, floor.id]; }), ); const roomRows = await transaction .insert(rooms) .values( DEFAULT_ROOMS.map((room) => { const floorId = floorIdByKey.get(`${room.campusName}/${room.buildingName}/${room.floorLevel}`); if (!floorId) { throw new Error("默认房间初始化失败"); } return { organizationId, floorId, name: room.name, code: room.code, capacity: room.capacity, }; }), ) .returning(); if (roomRows.length !== DEFAULT_ROOMS.length) { throw new Error("默认房间初始化失败"); } const roomIdByCode = new Map(roomRows.map((room) => [room.code, room.id])); const bedRows = await transaction .insert(beds) .values( DEFAULT_BEDS.map((bed) => { const roomId = roomIdByCode.get(bed.roomCode); if (!roomId) { throw new Error("默认床位初始化失败"); } return { organizationId, roomId, code: bed.code, status: bed.status, notes: bed.notes, }; }), ) .returning(); if (bedRows.length !== DEFAULT_BEDS.length) { throw new Error("默认床位初始化失败"); } const elderRows = await transaction .insert(elders) .values(DEFAULT_ELDERS.map((elder) => ({ ...elder, organizationId }))) .returning(); if (elderRows.length !== DEFAULT_ELDERS.length) { throw new Error("默认老人档案初始化失败"); } const elderIdByName = new Map(elderRows.map((elder) => [elder.name, elder.id])); const bedIdByCode = new Map(bedRows.map((bed) => [bed.code, bed.id])); await transaction.insert(admissions).values( DEFAULT_ADMISSIONS.map((admission) => { const elderId = elderIdByName.get(admission.elderName); const bedId = bedIdByCode.get(admission.bedCode); if (!elderId || !bedId) { throw new Error("默认入住初始化失败"); } return { organizationId, elderId, bedId, status: admission.status, dischargedAt: admission.status === "discharged" ? new Date() : undefined, notes: admission.notes, }; }), ); const now = new Date(); await transaction.insert(careTasks).values( DEFAULT_CARE_TASKS.map((task) => { const elderId = elderIdByName.get(task.elderName); if (!elderId) { throw new Error("默认护理任务初始化失败"); } const completedAt = task.completedHoursAgo === undefined ? undefined : new Date(now.getTime() - task.completedHoursAgo * 60 * 60 * 1000); return { organizationId, elderId, title: task.title, careType: task.careType, priority: task.priority, status: task.status, scheduledAt: new Date(now.getTime() + task.scheduledHoursOffset * 60 * 60 * 1000), assigneeLabel: task.assigneeLabel, executionNotes: task.executionNotes, completedAt, }; }), ); await transaction.insert(healthProfiles).values( DEFAULT_HEALTH_PROFILES.map((profile) => { const elderId = elderIdByName.get(profile.elderName); if (!elderId) { throw new Error("默认健康档案初始化失败"); } return { organizationId, elderId, allergyNotes: profile.allergyNotes, medicalHistory: profile.medicalHistory, medicationNotes: profile.medicationNotes, careRestrictions: profile.careRestrictions, emergencyNotes: profile.emergencyNotes, }; }), ); const vitalRows = await transaction .insert(vitalRecords) .values( DEFAULT_VITAL_RECORDS.map((vital) => { const elderId = elderIdByName.get(vital.elderName); if (!elderId) { throw new Error("默认生命体征初始化失败"); } return { organizationId, elderId, recordedAt: new Date(now.getTime() - vital.recordedHoursAgo * 60 * 60 * 1000), source: vital.source, systolicBp: vital.systolicBp, diastolicBp: vital.diastolicBp, heartRate: vital.heartRate, temperatureTenths: vital.temperatureTenths, spo2: vital.spo2, bloodGlucoseTenths: vital.bloodGlucoseTenths, weightTenths: vital.weightTenths, notes: vital.notes, }; }), ) .returning(); if (vitalRows.length !== DEFAULT_VITAL_RECORDS.length) { throw new Error("默认生命体征初始化失败"); } await transaction.insert(chronicConditions).values( DEFAULT_CHRONIC_CONDITIONS.map((condition) => { const elderId = elderIdByName.get(condition.elderName); if (!elderId) { throw new Error("默认慢病记录初始化失败"); } return { organizationId, elderId, name: condition.name, status: condition.status, treatmentNotes: condition.treatmentNotes, followUpNotes: condition.followUpNotes, }; }), ); await transaction.insert(healthAnomalyReviews).values( DEFAULT_HEALTH_REVIEWS.map((review) => { const elderId = elderIdByName.get(review.elderName); const vital = vitalRows[review.vitalIndex]; if (!elderId || !vital) { throw new Error("默认健康异常复核初始化失败"); } return { organizationId, elderId, vitalRecordId: vital.id, severity: review.severity, status: review.status, title: review.title, description: review.description, resolutionNotes: review.resolutionNotes, }; }), ); await transaction.insert(systemIncidents).values( DEFAULT_SYSTEM_INCIDENTS.map((incident) => ({ organizationId, severity: incident.severity, status: incident.status, title: incident.title, description: incident.description, source: incident.source, acknowledgedAt: incident.acknowledgedHoursAgo === undefined ? undefined : new Date(now.getTime() - incident.acknowledgedHoursAgo * 60 * 60 * 1000), resolvedAt: incident.resolvedHoursAgo === undefined ? undefined : new Date(now.getTime() - incident.resolvedHoursAgo * 60 * 60 * 1000), createdAt: new Date(now.getTime() - incident.createdHoursAgo * 60 * 60 * 1000), updatedAt: new Date( now.getTime() - (incident.resolvedHoursAgo ?? incident.acknowledgedHoursAgo ?? incident.createdHoursAgo) * 60 * 60 * 1000, ), })), ); }); }