diff --git a/apps/Backend/src/routes/claims.ts b/apps/Backend/src/routes/claims.ts index 4c56d55f..24706c9f 100755 --- a/apps/Backend/src/routes/claims.ts +++ b/apps/Backend/src/routes/claims.ts @@ -740,13 +740,16 @@ router.post( if (saved) resolvedNpiProvider = saved; } - // Collect attachments: appointment-level files + claim-level files + // Collect attachments: appointment-level files + claim-level files (deduped by filename+path) const apptFiles = await storage.getAppointmentFiles(Number(apt.id)); const claimFiles = (activeClaim as any)?.claimFiles ?? []; - const allFileMeta = [ - ...apptFiles, - ...claimFiles, - ] as Array<{ filename: string; mimeType?: string | null; filePath?: string | null }>; + const seenFileKeys = new Set(); + const allFileMeta = [...apptFiles, ...claimFiles].filter((f: any) => { + const key = `${f.filename ?? ""}::${f.filePath ?? ""}`; + if (seenFileKeys.has(key)) return false; + seenFileKeys.add(key); + return true; + }) as Array<{ filename: string; mimeType?: string | null; filePath?: string | null }>; const filesForQueue = allFileMeta.flatMap((f) => { if (!f.filePath) return []; @@ -1276,17 +1279,33 @@ router.put("/:id", async (req: Request, res: Response): Promise => { await syncAppointmentType(existingClaim.appointmentId, updatedCodes); } - // If new claimFiles are provided, append them (don't delete existing ones) + // If new claimFiles are provided, append only ones not already attached to this claim if (Array.isArray(req.body.claimFiles) && req.body.claimFiles.length > 0) { const { prisma: db } = await import("@repo/db/client"); - await db.claimFile.createMany({ - data: req.body.claimFiles.map((f: any) => ({ - claimId, - filename: String(f.filename || ""), - mimeType: String(f.mimeType || f.mime || ""), - ...(f.filePath ? { filePath: String(f.filePath) } : {}), - })), + const existingFiles = await db.claimFile.findMany({ + where: { claimId }, + select: { filename: true, filePath: true }, }); + const existingKeys = new Set( + existingFiles.map((f: any) => `${f.filename}::${f.filePath ?? ""}`) + ); + const seenKeys = new Set(); + const newFiles = req.body.claimFiles.filter((f: any) => { + const key = `${String(f.filename || "")}::${String(f.filePath || "")}`; + if (existingKeys.has(key) || seenKeys.has(key)) return false; + seenKeys.add(key); + return true; + }); + if (newFiles.length > 0) { + await db.claimFile.createMany({ + data: newFiles.map((f: any) => ({ + claimId, + filename: String(f.filename || ""), + mimeType: String(f.mimeType || f.mime || ""), + ...(f.filePath ? { filePath: String(f.filePath) } : {}), + })), + }); + } } // Explicitly pick only scalar fields — skip serviceLines and claimFiles (handled above)