export const VITAL_SOURCE_VALUES = ["manual", "device", "import"] as const; export type VitalSource = (typeof VITAL_SOURCE_VALUES)[number]; export const CHRONIC_CONDITION_STATUS_VALUES = ["active", "controlled", "resolved"] as const; export type ChronicConditionStatus = (typeof CHRONIC_CONDITION_STATUS_VALUES)[number]; export const HEALTH_REVIEW_STATUS_VALUES = ["pending", "reviewed", "resolved"] as const; export type HealthReviewStatus = (typeof HEALTH_REVIEW_STATUS_VALUES)[number]; export const HEALTH_REVIEW_SEVERITY_VALUES = ["info", "warning", "critical"] as const; export type HealthReviewSeverity = (typeof HEALTH_REVIEW_SEVERITY_VALUES)[number]; export const VITAL_SOURCE_LABELS: Record = { manual: "手工录入", device: "设备采集", import: "批量导入", }; export const CHRONIC_CONDITION_STATUS_LABELS: Record = { active: "持续管理", controlled: "控制稳定", resolved: "已结束", }; export const HEALTH_REVIEW_STATUS_LABELS: Record = { pending: "待复核", reviewed: "已复核", resolved: "已处理", }; export const HEALTH_REVIEW_SEVERITY_LABELS: Record = { info: "提示", warning: "预警", critical: "紧急", }; export type HealthElderOption = { id: string; name: string; careLevel: string; status: string; }; export type HealthProfile = { id: string; organizationId: string; elderId: string; elderName: string; allergyNotes: string; medicalHistory: string; medicationNotes: string; careRestrictions: string; emergencyNotes: string; createdAt: string; updatedAt: string; }; export type VitalRecord = { id: string; organizationId: string; elderId: string; elderName: string; recordedAt: string; source: VitalSource; systolicBp?: number; diastolicBp?: number; heartRate?: number; temperatureTenths?: number; spo2?: number; bloodGlucoseTenths?: number; weightTenths?: number; notes: string; createdByAccountId?: string; createdByName?: string; createdAt: string; updatedAt: string; }; export type ChronicCondition = { id: string; organizationId: string; elderId: string; elderName: string; name: string; status: ChronicConditionStatus; diagnosedAt?: string; treatmentNotes: string; followUpNotes: string; createdAt: string; updatedAt: string; }; export type HealthAnomalyReview = { id: string; organizationId: string; elderId: string; elderName: string; vitalRecordId?: string; severity: HealthReviewSeverity; status: HealthReviewStatus; title: string; description: string; reviewedByAccountId?: string; reviewedByName?: string; reviewedAt?: string; resolutionNotes: string; createdAt: string; updatedAt: string; }; export type HealthAdminMetrics = { eldersWithProfiles: number; vitalsToday: number; activeChronicConditions: number; pendingReviews: number; }; export type HealthAdminData = { elders: HealthElderOption[]; profiles: HealthProfile[]; vitals: VitalRecord[]; chronicConditions: ChronicCondition[]; reviews: HealthAnomalyReview[]; metrics: HealthAdminMetrics; }; export type HealthProfileInput = { allergyNotes: string; medicalHistory: string; medicationNotes: string; careRestrictions: string; emergencyNotes: string; }; export type VitalRecordInput = { elderId: string; recordedAt: Date; source: VitalSource; systolicBp?: number; diastolicBp?: number; heartRate?: number; temperatureTenths?: number; spo2?: number; bloodGlucoseTenths?: number; weightTenths?: number; notes: string; }; export type ChronicConditionInput = { elderId: string; name: string; status: ChronicConditionStatus; diagnosedAt?: Date; treatmentNotes: string; followUpNotes: string; }; export type HealthReviewUpdateInput = { status: HealthReviewStatus; resolutionNotes: string; }; type ValidationSuccess = { success: true; data: T; }; type ValidationFailure = { success: false; reason: string; }; export type ValidationResult = ValidationSuccess | ValidationFailure; function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function readString(source: Record, key: string): string { const value = source[key]; return typeof value === "string" ? value.trim() : ""; } function readOptionalInteger(source: Record, key: string): number | undefined | null { const value = source[key]; if (value === undefined || value === null || value === "") { return undefined; } const numeric = typeof value === "number" ? value : Number(value); return Number.isInteger(numeric) ? numeric : null; } function readEnum(value: unknown, values: readonly T[]): T | null { return typeof value === "string" ? values.find((item) => item === value) ?? null : null; } function readOptionalDate(source: Record, key: string): Date | undefined | null { const value = source[key]; if (value === undefined || value === null || value === "") { return undefined; } if (typeof value !== "string") { return null; } const date = new Date(value); return Number.isNaN(date.getTime()) ? null : date; } export function validateHealthProfileInput(value: unknown): ValidationResult { if (!isRecord(value)) { return { success: false, reason: "请求数据格式无效" }; } return { success: true, data: { allergyNotes: readString(value, "allergyNotes"), medicalHistory: readString(value, "medicalHistory"), medicationNotes: readString(value, "medicationNotes"), careRestrictions: readString(value, "careRestrictions"), emergencyNotes: readString(value, "emergencyNotes"), }, }; } export function validateVitalRecordInput(value: unknown): ValidationResult { if (!isRecord(value)) { return { success: false, reason: "请求数据格式无效" }; } const elderId = readString(value, "elderId"); if (!elderId) { return { success: false, reason: "老人不能为空" }; } const recordedAt = readOptionalDate(value, "recordedAt"); if (!recordedAt) { return { success: false, reason: "记录时间无效" }; } const source = readEnum(value.source, VITAL_SOURCE_VALUES); if (!source) { return { success: false, reason: "记录来源无效" }; } const integerKeys = [ "systolicBp", "diastolicBp", "heartRate", "temperatureTenths", "spo2", "bloodGlucoseTenths", "weightTenths", ] as const; const parsed: Partial> = {}; for (const key of integerKeys) { const numberValue = readOptionalInteger(value, key); if (numberValue === null) { return { success: false, reason: "生命体征数值需为整数" }; } if (numberValue !== undefined) { parsed[key] = numberValue; } } return { success: true, data: { elderId, recordedAt, source, notes: readString(value, "notes"), ...parsed, }, }; } export function validateChronicConditionInput(value: unknown): ValidationResult { if (!isRecord(value)) { return { success: false, reason: "请求数据格式无效" }; } const elderId = readString(value, "elderId"); const name = readString(value, "name"); if (!elderId || !name) { return { success: false, reason: "老人和慢病名称不能为空" }; } const status = readEnum(value.status, CHRONIC_CONDITION_STATUS_VALUES); if (!status) { return { success: false, reason: "慢病状态无效" }; } const diagnosedAt = readOptionalDate(value, "diagnosedAt"); if (diagnosedAt === null) { return { success: false, reason: "诊断日期无效" }; } return { success: true, data: { elderId, name, status, diagnosedAt, treatmentNotes: readString(value, "treatmentNotes"), followUpNotes: readString(value, "followUpNotes"), }, }; } export function validateHealthReviewUpdateInput(value: unknown): ValidationResult { if (!isRecord(value)) { return { success: false, reason: "请求数据格式无效" }; } const status = readEnum(value.status, HEALTH_REVIEW_STATUS_VALUES); if (!status) { return { success: false, reason: "复核状态无效" }; } return { success: true, data: { status, resolutionNotes: readString(value, "resolutionNotes"), }, }; }