import { Appointment, AppointmentProcedure, InsertAppointmentProcedure, Patient, UpdateAppointmentProcedure, } from "@repo/db/types"; import { prisma as db } from "@repo/db/client"; export interface AppointmentFileMeta { filename: string; mimeType?: string | null; filePath?: string | null; } export interface IAppointmentProceduresStorage { getByAppointmentId(appointmentId: number): Promise; getPrefillDataByAppointmentId(appointmentId: number): Promise<{ appointment: Appointment; patient: Patient; procedures: AppointmentProcedure[]; npiProviderId: number | null; appointmentFiles: AppointmentFileMeta[]; } | null>; saveForAppointment(params: { appointmentId: number; patientId: number; npiProviderId: number | null; procedures: Array<{ procedureCode: string; fee?: number | null; toothNumber?: string | null; toothSurface?: string | null; }>; attachments?: AppointmentFileMeta[]; }): Promise; createProcedure( data: InsertAppointmentProcedure ): Promise; createProceduresBulk(data: InsertAppointmentProcedure[]): Promise; updateProcedure( id: number, data: UpdateAppointmentProcedure ): Promise; deleteProcedure(id: number): Promise; clearByAppointmentId(appointmentId: number): Promise; getAppointmentFiles(appointmentId: number): Promise; getAppointmentIdsWithProcedures(ids: number[]): Promise>; } export const appointmentProceduresStorage: IAppointmentProceduresStorage = { async getByAppointmentId( appointmentId: number ): Promise { return db.appointmentProcedure.findMany({ where: { appointmentId }, orderBy: { createdAt: "asc" }, }); }, async getPrefillDataByAppointmentId(appointmentId: number) { const appointment = await db.appointment.findUnique({ where: { id: appointmentId }, include: { patient: true, procedures: { orderBy: { createdAt: "asc" }, }, files: { orderBy: { id: "asc" }, }, }, }); if (!appointment) { return null; } const npiProviderId = appointment.procedures[0]?.npiProviderId ?? null; return { appointment, patient: appointment.patient, procedures: appointment.procedures, npiProviderId, appointmentFiles: (appointment.files as any[]).map((f) => ({ id: f.id, filename: f.filename, mimeType: f.mimeType, filePath: f.filePath, })), }; }, async saveForAppointment({ appointmentId, patientId, npiProviderId, procedures, attachments }) { await db.appointmentProcedure.deleteMany({ where: { appointmentId } }); if (attachments?.length) { await db.appointmentFile.deleteMany({ where: { appointmentId } }); await db.appointmentFile.createMany({ data: attachments.map((a) => ({ appointmentId, filename: a.filename, mimeType: a.mimeType ?? null, filePath: a.filePath ?? null, })), }); } if (!procedures.length) return 0; const result = await db.appointmentProcedure.createMany({ data: procedures.map((p) => ({ appointmentId, patientId, npiProviderId: npiProviderId ?? null, procedureCode: p.procedureCode, fee: p.fee != null ? p.fee : null, toothNumber: p.toothNumber || null, toothSurface: p.toothSurface || null, source: "MANUAL" as const, })), }); return result.count; }, async createProcedure( data: InsertAppointmentProcedure ): Promise { return db.appointmentProcedure.create({ data: data as AppointmentProcedure, }); }, async createProceduresBulk( data: InsertAppointmentProcedure[] ): Promise { const result = await db.appointmentProcedure.createMany({ data: data as any[], }); return result.count; }, async updateProcedure( id: number, data: UpdateAppointmentProcedure ): Promise { return db.appointmentProcedure.update({ where: { id }, data: data as any, }); }, async deleteProcedure(id: number): Promise { await db.appointmentProcedure.delete({ where: { id }, }); }, async clearByAppointmentId(appointmentId: number): Promise { await db.appointmentProcedure.deleteMany({ where: { appointmentId }, }); }, async getAppointmentIdsWithProcedures(ids: number[]): Promise> { if (!ids.length) return new Set(); const rows = await db.appointmentProcedure.findMany({ where: { appointmentId: { in: ids } }, select: { appointmentId: true }, distinct: ["appointmentId"], }); return new Set(rows.map((r: any) => r.appointmentId)); }, async getAppointmentFiles(appointmentId: number): Promise { const rows = await db.appointmentFile.findMany({ where: { appointmentId }, orderBy: { id: "asc" }, }); return rows.map((f: any) => ({ id: f.id, filename: f.filename, mimeType: f.mimeType, filePath: f.filePath, })); }, };