feat(claimStatus) - Feature done

This commit is contained in:
2025-09-19 03:39:54 +05:30
parent 6e97e5ab40
commit c60b7ac954
2 changed files with 241 additions and 164 deletions

View File

@@ -25,6 +25,7 @@
"node-cron": "^4.2.1", "node-cron": "^4.2.1",
"passport": "^0.7.0", "passport": "^0.7.0",
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
"pdfkit": "^0.17.2",
"ws": "^8.18.0", "ws": "^8.18.0",
"zod": "^3.24.2", "zod": "^3.24.2",
"zod-validation-error": "^3.4.0" "zod-validation-error": "^3.4.0"
@@ -40,6 +41,7 @@
"@types/node": "20.16.11", "@types/node": "20.16.11",
"@types/passport": "^1.0.16", "@types/passport": "^1.0.16",
"@types/passport-local": "^1.0.38", "@types/passport-local": "^1.0.38",
"@types/pdfkit": "^0.17.3",
"@types/ws": "^8.5.13", "@types/ws": "^8.5.13",
"ts-node-dev": "^2.0.0" "ts-node-dev": "^2.0.0"
} }

View File

@@ -4,209 +4,284 @@ import { storage } from "../storage";
import { forwardToSeleniumInsuranceEligibilityAgent } from "../services/seleniumInsuranceEligibilityClient"; import { forwardToSeleniumInsuranceEligibilityAgent } from "../services/seleniumInsuranceEligibilityClient";
import fs from "fs/promises"; import fs from "fs/promises";
import path from "path"; import path from "path";
import PDFDocument from "pdfkit";
import { forwardToSeleniumInsuranceClaimStatusAgent } from "../services/seleniumInsuranceClaimStatusClient"; import { forwardToSeleniumInsuranceClaimStatusAgent } from "../services/seleniumInsuranceClaimStatusClient";
import fsSync from "fs";
const router = Router(); const router = Router();
router.post("/eligibility-check", async (req: Request, res: Response): Promise<any> => { router.post(
if (!req.body.data) { "/eligibility-check",
return res async (req: Request, res: Response): Promise<any> => {
.status(400) if (!req.body.data) {
.json({ error: "Missing Insurance Eligibility data for selenium" }); return res
} .status(400)
.json({ error: "Missing Insurance Eligibility data for selenium" });
if (!req.user || !req.user.id) {
return res.status(401).json({ error: "Unauthorized: user info missing" });
}
try {
const insuranceEligibilityData = JSON.parse(req.body.data);
const credentials = await storage.getInsuranceCredentialByUserAndSiteKey(
req.user.id,
insuranceEligibilityData.insuranceSiteKey
);
if (!credentials) {
return res.status(404).json({
error:
"No insurance credentials found for this provider, Kindly Update this at Settings Page.",
});
} }
const enrichedData = { if (!req.user || !req.user.id) {
...insuranceEligibilityData, return res.status(401).json({ error: "Unauthorized: user info missing" });
massdhpUsername: credentials.username, }
massdhpPassword: credentials.password,
};
const result = try {
await forwardToSeleniumInsuranceEligibilityAgent(enrichedData); const insuranceEligibilityData = JSON.parse(req.body.data);
// ✅ Step 1: Check result and update patient status const credentials = await storage.getInsuranceCredentialByUserAndSiteKey(
const patient = await storage.getPatientByInsuranceId( req.user.id,
insuranceEligibilityData.memberId insuranceEligibilityData.insuranceSiteKey
); );
if (!credentials) {
return res.status(404).json({
error:
"No insurance credentials found for this provider, Kindly Update this at Settings Page.",
});
}
if (patient && patient.id !== undefined) { const enrichedData = {
const newStatus = result.eligibility === "Y" ? "active" : "inactive"; ...insuranceEligibilityData,
await storage.updatePatient(patient.id, { status: newStatus }); massdhpUsername: credentials.username,
result.patientUpdateStatus = `Patient status updated to ${newStatus}`; massdhpPassword: credentials.password,
};
// ✅ Step 2: Handle PDF Upload const result =
if (result.pdf_path && result.pdf_path.endsWith(".pdf")) { await forwardToSeleniumInsuranceEligibilityAgent(enrichedData);
const pdfBuffer = await fs.readFile(result.pdf_path);
const groupTitle = "Insurance Status PDFs"; // ✅ Step 1: Check result and update patient status
const groupTitleKey = "INSURANCE_STATUS_PDFs" const patient = await storage.getPatientByInsuranceId(
const groupCategory = "ELIGIBILITY_STATUS"; insuranceEligibilityData.memberId
);
let group = await storage.findPdfGroupByPatientTitleKeyAndCategory( if (patient && patient.id !== undefined) {
patient.id, const newStatus = result.eligibility === "Y" ? "active" : "inactive";
groupTitleKey, await storage.updatePatient(patient.id, { status: newStatus });
groupCategory result.patientUpdateStatus = `Patient status updated to ${newStatus}`;
);
// Step 2b: Create group if it doesnt exist // Step 2: Handle PDF Upload
if (!group) { if (result.pdf_path && result.pdf_path.endsWith(".pdf")) {
group = await storage.createPdfGroup( const pdfBuffer = await fs.readFile(result.pdf_path);
const groupTitle = "Insurance Status PDFs";
const groupTitleKey = "INSURANCE_STATUS_PDFs";
const groupCategory = "ELIGIBILITY_STATUS";
let group = await storage.findPdfGroupByPatientTitleKeyAndCategory(
patient.id, patient.id,
groupTitle,
groupTitleKey, groupTitleKey,
groupCategory groupCategory
); );
// Step 2b: Create group if it doesnt exist
if (!group) {
group = await storage.createPdfGroup(
patient.id,
groupTitle,
groupTitleKey,
groupCategory
);
}
if (!group?.id) {
throw new Error("PDF group creation failed: missing group ID");
}
await storage.createPdfFile(
group.id,
path.basename(result.pdf_path),
pdfBuffer
);
await fs.unlink(result.pdf_path);
result.pdfUploadStatus = `PDF saved to group: ${group.title}`;
} else {
result.pdfUploadStatus =
"No valid PDF path provided by Selenium, Couldn't upload pdf to server.";
} }
if (!group?.id) {
throw new Error("PDF group creation failed: missing group ID");
}
await storage.createPdfFile(
group.id,
path.basename(result.pdf_path),
pdfBuffer
);
await fs.unlink(result.pdf_path);
result.pdfUploadStatus = `PDF saved to group: ${group.title}`;
} else { } else {
result.pdfUploadStatus = result.patientUpdateStatus =
"No valid PDF path provided by Selenium, Couldn't upload pdf to server."; "Patient not found or missing ID; no update performed";
} }
} else {
result.patientUpdateStatus =
"Patient not found or missing ID; no update performed";
}
res.json({ res.json({
patientUpdateStatus: result.patientUpdateStatus, patientUpdateStatus: result.patientUpdateStatus,
pdfUploadStatus: result.pdfUploadStatus, pdfUploadStatus: result.pdfUploadStatus,
}); });
} catch (err: any) {
} catch (err: any) { console.error(err);
console.error(err); return res.status(500).json({
return res.status(500).json({ error: err.message || "Failed to forward to selenium agent",
error: err.message || "Failed to forward to selenium agent",
});
}
});
router.post("/claim-status-check", async (req: Request, res: Response): Promise<any> => {
if (!req.body.data) {
return res
.status(400)
.json({ error: "Missing Insurance Status data for selenium" });
}
if (!req.user || !req.user.id) {
return res.status(401).json({ error: "Unauthorized: user info missing" });
}
try {
const insuranceClaimStatusData = JSON.parse(req.body.data);
const credentials = await storage.getInsuranceCredentialByUserAndSiteKey(
req.user.id,
insuranceClaimStatusData.insuranceSiteKey
);
if (!credentials) {
return res.status(404).json({
error:
"No insurance credentials found for this provider, Kindly Update this at Settings Page.",
}); });
} }
}
);
const enrichedData = { router.post(
...insuranceClaimStatusData, "/claim-status-check",
massdhpUsername: credentials.username, async (req: Request, res: Response): Promise<any> => {
massdhpPassword: credentials.password, if (!req.body.data) {
}; return res
.status(400)
.json({ error: "Missing Insurance Status data for selenium" });
}
const result = if (!req.user || !req.user.id) {
await forwardToSeleniumInsuranceClaimStatusAgent(enrichedData); return res.status(401).json({ error: "Unauthorized: user info missing" });
}
async function imageToPdfBuffer(imagePath: string): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
try {
const doc = new PDFDocument({ autoFirstPage: false });
const chunks: Uint8Array[] = [];
// ✅ Step 1: Check result // collect data chunks
const patient = await storage.getPatientByInsuranceId( doc.on("data", (chunk: any) => chunks.push(chunk));
insuranceClaimStatusData.memberId doc.on("end", () => resolve(Buffer.concat(chunks)));
); doc.on("error", (err: any) => reject(err));
if (patient && patient.id !== undefined) { const A4_WIDTH = 595.28; // points
// ✅ Step 2: Handle PDF Upload const A4_HEIGHT = 841.89; // points
if (result.pdf_path && result.pdf_path.endsWith(".pdf")) {
const pdfBuffer = await fs.readFile(result.pdf_path);
const groupTitle = "Insurance Status PDFs"; doc.addPage({ size: [A4_WIDTH, A4_HEIGHT] });
const groupTitleKey = "INSURANCE_STATUS_PDFs"
const groupCategory = "CLAIM_STATUS";
let group = await storage.findPdfGroupByPatientTitleKeyAndCategory( doc.image(imagePath, 0, 0, {
patient.id, fit: [A4_WIDTH, A4_HEIGHT],
groupTitleKey, align: "center",
groupCategory valign: "center",
); });
// Step 2b: Create group if it doesnt exist doc.end();
if (!group) { } catch (err) {
group = await storage.createPdfGroup( reject(err);
}
});
}
try {
const insuranceClaimStatusData = JSON.parse(req.body.data);
const credentials = await storage.getInsuranceCredentialByUserAndSiteKey(
req.user.id,
insuranceClaimStatusData.insuranceSiteKey
);
if (!credentials) {
return res.status(404).json({
error:
"No insurance credentials found for this provider, Kindly Update this at Settings Page.",
});
}
const enrichedData = {
...insuranceClaimStatusData,
massdhpUsername: credentials.username,
massdhpPassword: credentials.password,
};
const result =
await forwardToSeleniumInsuranceClaimStatusAgent(enrichedData);
// ✅ Step 1: Check result
const patient = await storage.getPatientByInsuranceId(
insuranceClaimStatusData.memberId
);
if (patient && patient.id !== undefined) {
let pdfBuffer: Buffer | null = null;
let generatedPdfPath: string | null = null;
if (
result.ss_path &&
(result.ss_path.endsWith(".png") ||
result.ss_path.endsWith(".jpg") ||
result.ss_path.endsWith(".jpeg"))
) {
try {
// Ensure file exists
if (!fsSync.existsSync(result.ss_path)) {
throw new Error(`Screenshot file not found: ${result.ss_path}`);
}
// Convert image to PDF buffer
pdfBuffer = await imageToPdfBuffer(result.ss_path);
// Optionally write generated PDF to temp path (so name is available for createPdfFile)
const pdfFileName = `claimStatus_${insuranceClaimStatusData.memberId}_${Date.now()}.pdf`;
generatedPdfPath = path.join(
path.dirname(result.ss_path),
pdfFileName
);
await fs.writeFile(generatedPdfPath, pdfBuffer);
} catch (err) {
console.error("Failed to convert screenshot to PDF:", err);
result.pdfUploadStatus = `Failed to convert screenshot to PDF: ${String(err)}`;
}
} else {
result.pdfUploadStatus =
"No valid PDF or screenshot path provided by Selenium; nothing to upload.";
}
if (pdfBuffer && generatedPdfPath) {
const groupTitle = "Insurance Status PDFs";
const groupTitleKey = "INSURANCE_STATUS_PDFs";
const groupCategory = "CLAIM_STATUS";
let group = await storage.findPdfGroupByPatientTitleKeyAndCategory(
patient.id, patient.id,
groupTitle,
groupTitleKey, groupTitleKey,
groupCategory groupCategory
); );
// Create group if missing
if (!group) {
group = await storage.createPdfGroup(
patient.id,
groupTitle,
groupTitleKey,
groupCategory
);
}
if (!group?.id) {
throw new Error("PDF group creation failed: missing group ID");
}
// Use the basename for storage
const basename = path.basename(generatedPdfPath);
await storage.createPdfFile(group.id, basename, pdfBuffer);
// Clean up temp files:
try {
// remove generated PDF file (if it was created during conversion)
if (
generatedPdfPath &&
fsSync.existsSync(generatedPdfPath) &&
generatedPdfPath !== result.pdf_path
) {
await fs.unlink(generatedPdfPath);
}
// remove screenshot (if provided by Selenium) to avoid lingering temp files
if (result.ss_path && fsSync.existsSync(result.ss_path)) {
await fs.unlink(result.ss_path);
}
} catch (cleanupErr) {
console.warn("Cleanup error (non-fatal):", cleanupErr);
}
result.pdfUploadStatus = `PDF saved to group: ${group.title}`;
} }
if (!group?.id) {
throw new Error("PDF group creation failed: missing group ID");
}
await storage.createPdfFile(
group.id,
path.basename(result.pdf_path),
pdfBuffer
);
await fs.unlink(result.pdf_path);
result.pdfUploadStatus = `PDF saved to group: ${group.title}`;
} else { } else {
result.pdfUploadStatus = result.patientUpdateStatus =
"No valid PDF path provided by Selenium, Couldn't upload pdf to server."; "Patient not found or missing ID; no update performed";
} }
} else {
result.patientUpdateStatus = res.json({
"Patient not found or missing ID; no update performed"; pdfUploadStatus: result.pdfUploadStatus,
});
} catch (err: any) {
console.error(err);
return res.status(500).json({
error: err.message || "Failed to forward to selenium agent",
});
} }
res.json({
patientUpdateStatus: result.patientUpdateStatus,
pdfUploadStatus: result.pdfUploadStatus,
});
} catch (err: any) {
console.error(err);
return res.status(500).json({
error: err.message || "Failed to forward to selenium agent",
});
} }
}); );
export default router; export default router;