fix: dedupe claim attachments to prevent duplicate uploads to insurance
Claim attachments were being appended without checking for existing duplicates, causing files (e.g. the same PDF) to be sent to the insurance clearinghouse multiple times.
This commit is contained in:
@@ -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<string>();
|
||||
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<any> => {
|
||||
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<string>();
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user