import { Prisma } from '../generated/prisma/client.js'; const IMPLANT_CATALOG_SELECT = { id: true, modelCode: true, manufacturer: true, name: true, isValve: true, pressureLevels: true, isPressureAdjustable: true, notes: true, } as const; export const PATIENT_LIFECYCLE_INCLUDE = { hospital: { select: { id: true, name: true } }, doctor: { select: { departmentId: true, groupId: true } }, surgeries: { include: { devices: { include: { implantCatalog: { select: IMPLANT_CATALOG_SELECT, }, }, }, }, orderBy: { surgeryDate: 'desc' }, }, devices: { include: { surgery: { select: { id: true, surgeryDate: true, surgeryName: true, }, }, implantCatalog: { select: IMPLANT_CATALOG_SELECT, }, taskItems: { include: { task: true, }, }, }, }, } as const satisfies Prisma.PatientInclude; export type PatientLifecycleSource = Prisma.PatientGetPayload<{ include: typeof PATIENT_LIFECYCLE_INCLUDE; }>; export function buildPatientLifecyclePayload(patient: PatientLifecycleSource) { return { patient: buildPatientLifecyclePatient(patient), lifecycle: buildPatientLifecycleEvents(patient), }; } export function buildPatientLifecyclePatient(patient: PatientLifecycleSource) { return { id: toJsonNumber(patient.id), name: patient.name, inpatientNo: patient.inpatientNo, phone: patient.phone, projectName: patient.projectName, }; } export function buildPatientLifecycleEvents(patient: PatientLifecycleSource) { const surgeryEvents = patient.surgeries.map((surgery, index, surgeries) => ({ eventType: 'SURGERY' as const, occurredAt: surgery.surgeryDate, hospital: patient.hospital, surgery: { id: toJsonNumber(surgery.id), surgeryDate: surgery.surgeryDate, surgeryName: surgery.surgeryName, surgeonName: surgery.surgeonName, primaryDisease: surgery.primaryDisease, hydrocephalusTypes: surgery.hydrocephalusTypes, previousShuntSurgeryDate: surgery.previousShuntSurgeryDate, shuntSurgeryCount: surgeries.length - index, }, devices: surgery.devices.map((device) => ({ id: toJsonNumber(device.id), status: device.status, isAbandoned: device.isAbandoned, currentPressure: device.currentPressure, initialPressure: device.initialPressure, implantModel: device.implantModel, implantManufacturer: device.implantManufacturer, implantName: device.implantName, isValve: device.isValve, isPressureAdjustable: device.isPressureAdjustable, shuntMode: device.shuntMode, distalShuntDirection: device.distalShuntDirection, proximalPunctureAreas: device.proximalPunctureAreas, valvePlacementSites: device.valvePlacementSites, implantCatalog: device.implantCatalog, })), })); const taskEvents = patient.devices.flatMap((device) => device.taskItems.flatMap((taskItem) => { if (!taskItem.task) { return []; } const task = taskItem.task; return [ { eventType: 'TASK_PRESSURE_ADJUSTMENT' as const, occurredAt: task.createdAt, hospital: patient.hospital, device: { id: toJsonNumber(device.id), status: device.status, isAbandoned: device.isAbandoned, currentPressure: device.currentPressure, implantModel: device.implantModel, implantManufacturer: device.implantManufacturer, implantName: device.implantName, isValve: device.isValve, isPressureAdjustable: device.isPressureAdjustable, }, surgery: device.surgery ? { id: toJsonNumber(device.surgery.id), surgeryDate: device.surgery.surgeryDate, surgeryName: device.surgery.surgeryName, } : null, task: { id: toJsonNumber(task.id), status: task.status, createdAt: task.createdAt, }, taskItem: { id: toJsonNumber(taskItem.id), oldPressure: taskItem.oldPressure, targetPressure: taskItem.targetPressure, }, }, ]; }), ); return [...surgeryEvents, ...taskEvents].sort( (left, right) => new Date(right.occurredAt).getTime() - new Date(left.occurredAt).getTime(), ); } function toJsonNumber(value: number | bigint | null | undefined) { if (value == null) { return null; } return typeof value === 'bigint' ? Number(value) : value; }