From bbd7a0089f5949225d0d4deaf51cafac0351a634 Mon Sep 17 00:00:00 2001 From: Potenz Date: Mon, 14 Jul 2025 18:12:21 +0530 Subject: [PATCH] eligibility check - checkpoint1 --- apps/Backend/src/routes/claims.ts | 4 +- apps/Backend/src/routes/index.ts | 3 + .../src/routes/insuranceEligibility.ts | 68 +--- .../src/services/seleniumClaimClient.ts | 4 +- .../src/services/seleniumEligibilityClient.ts | 52 --- .../seleniumInsuranceEligibilityClient.ts | 27 ++ .../claims/selenium-task-banner.tsx | 23 +- apps/Frontend/src/pages/claims-page.tsx | 23 +- .../src/pages/insurance-eligibility-page.tsx | 95 ++++- .../slices/seleniumClaimSubmitTaskSlice.ts | 33 ++ ...s => seleniumEligibilityCheckTaskSlice.ts} | 8 +- apps/Frontend/src/redux/store.ts | 6 +- apps/SeleniumService/agent.py | 87 ++++- ...orker.py => selenium_claimSubmitWorker.py} | 0 .../selenium_eligibilityCheckWorker.py | 364 ++++++++++++++++++ 15 files changed, 637 insertions(+), 160 deletions(-) delete mode 100644 apps/Backend/src/services/seleniumEligibilityClient.ts create mode 100644 apps/Backend/src/services/seleniumInsuranceEligibilityClient.ts create mode 100644 apps/Frontend/src/redux/slices/seleniumClaimSubmitTaskSlice.ts rename apps/Frontend/src/redux/slices/{seleniumTaskSlice.ts => seleniumEligibilityCheckTaskSlice.ts} (70%) rename apps/SeleniumService/{selenium_worker.py => selenium_claimSubmitWorker.py} (100%) create mode 100644 apps/SeleniumService/selenium_eligibilityCheckWorker.py diff --git a/apps/Backend/src/routes/claims.ts b/apps/Backend/src/routes/claims.ts index f06aa5e..bad11e5 100644 --- a/apps/Backend/src/routes/claims.ts +++ b/apps/Backend/src/routes/claims.ts @@ -4,7 +4,7 @@ import { storage } from "../storage"; import { z } from "zod"; import { ClaimUncheckedCreateInputObjectSchema } from "@repo/db/usedSchemas"; import multer from "multer"; -import { forwardToSeleniumAgent } from "../services/seleniumClaimClient"; +import { forwardToSeleniumClaimAgent } from "../services/seleniumClaimClient"; import path from "path"; import axios from "axios"; import fs from "fs"; @@ -101,7 +101,7 @@ router.post( massdhpPassword: credentials.password, }; - const result = await forwardToSeleniumAgent(enrichedData, [ + const result = await forwardToSeleniumClaimAgent(enrichedData, [ ...pdfs, ...images, ]); diff --git a/apps/Backend/src/routes/index.ts b/apps/Backend/src/routes/index.ts index 7e8a16a..2c594a3 100644 --- a/apps/Backend/src/routes/index.ts +++ b/apps/Backend/src/routes/index.ts @@ -7,6 +7,7 @@ import pdfExtractionRoutes from './pdfExtraction'; import claimsRoutes from './claims'; import insuranceCredsRoutes from './insuranceCreds'; import documentRoutes from './documents'; +import insuranceEligibilityRoutes from './insuranceEligibility' const router = Router(); @@ -18,5 +19,7 @@ router.use('/pdfExtraction', pdfExtractionRoutes); router.use('/claims', claimsRoutes); router.use('/insuranceCreds', insuranceCredsRoutes); router.use('/documents', documentRoutes); +router.use('/insuranceEligibility', insuranceEligibilityRoutes); + export default router; \ No newline at end of file diff --git a/apps/Backend/src/routes/insuranceEligibility.ts b/apps/Backend/src/routes/insuranceEligibility.ts index 72d3df3..fa52d17 100644 --- a/apps/Backend/src/routes/insuranceEligibility.ts +++ b/apps/Backend/src/routes/insuranceEligibility.ts @@ -1,46 +1,17 @@ import { Router } from "express"; import { Request, Response } from "express"; import { storage } from "../storage"; -import { z } from "zod"; -import multer from "multer"; -import { forwardToSeleniumAgent } from "../services/seleniumClaimClient"; +import { forwardToSeleniumInsuranceEligibilityAgent } from "../services/seleniumInsuranceEligibilityClient"; const router = Router(); - - - -// Routes -const multerStorage = multer.memoryStorage(); // NO DISK -const upload = multer({ - storage: multerStorage, - limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit per file - fileFilter: (req, file, cb) => { - const allowed = [ - "application/pdf", - "image/jpeg", - "image/png", - "image/webp", - ]; - if (allowed.includes(file.mimetype)) { - cb(null, true); - } else { - cb(new Error("Unsupported file type")); - } - }, -}); - router.post( - "/selenium", - upload.fields([ - { name: "pdfs", maxCount: 10 }, - { name: "images", maxCount: 10 }, - ]), + "/check", async (req: Request, res: Response): Promise => { - if (!req.files || !req.body.data) { + if (!req.body.data) { return res .status(400) - .json({ error: "Missing files or claim data for selenium" }); + .json({ error: "Missing Insurance Eligibility data for selenium" }); } if (!req.user || !req.user.id) { @@ -48,37 +19,29 @@ router.post( } try { - const claimData = JSON.parse(req.body.data); - const pdfs = - (req.files as Record).pdfs ?? []; - const images = - (req.files as Record).images ?? []; + const insuranceEligibilityData = JSON.parse(req.body.data); const credentials = await storage.getInsuranceCredentialByUserAndSiteKey( req.user.id, - claimData.insuranceSiteKey + insuranceEligibilityData.insuranceSiteKey ); if (!credentials) { - return res - .status(404) - .json({ error: "No insurance credentials found for this provider." }); + return res.status(404).json({ + error: + "No insurance credentials found for this provider, Kindly Update this at Settings Page.", + }); } const enrichedData = { - ...claimData, + ...insuranceEligibilityData, massdhpUsername: credentials.username, massdhpPassword: credentials.password, }; - const result = await forwardToSeleniumAgent(enrichedData, [ - ...pdfs, - ...images, - ]); + const result = + await forwardToSeleniumInsuranceEligibilityAgent(enrichedData); - res.json({ - ...result, - claimId: claimData.claimId, - }); + res.json(result); } catch (err: any) { console.error(err); return res.status(500).json({ @@ -88,5 +51,4 @@ router.post( } ); - -export default router; \ No newline at end of file +export default router; diff --git a/apps/Backend/src/services/seleniumClaimClient.ts b/apps/Backend/src/services/seleniumClaimClient.ts index 5044061..d00b457 100644 --- a/apps/Backend/src/services/seleniumClaimClient.ts +++ b/apps/Backend/src/services/seleniumClaimClient.ts @@ -12,7 +12,7 @@ export interface SeleniumPayload { }[]; } -export async function forwardToSeleniumAgent( +export async function forwardToSeleniumClaimAgent( claimData: any, files: Express.Multer.File[] ): Promise { @@ -37,7 +37,7 @@ export async function forwardToSeleniumAgent( }; const result = await axios.post( - "http://localhost:5002/start-workflow", + "http://localhost:5002/claimsubmit", payload ); if (result.data.status === "error") { diff --git a/apps/Backend/src/services/seleniumEligibilityClient.ts b/apps/Backend/src/services/seleniumEligibilityClient.ts deleted file mode 100644 index d658f9d..0000000 --- a/apps/Backend/src/services/seleniumEligibilityClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import axios from "axios"; - -export interface SeleniumPayload { - claim: any; - pdfs: { - originalname: string; - bufferBase64: string; - }[]; - images: { - originalname: string; - bufferBase64: string; - }[]; -} - -export async function forwardToSeleniumAgent( - claimData: any, - files: Express.Multer.File[] -): Promise { - const pdfs = files - .filter((file) => file.mimetype === "application/pdf") - .map((file) => ({ - originalname: file.originalname, - bufferBase64: file.buffer.toString("base64"), - })); - - const images = files - .filter((file) => file.mimetype.startsWith("image/")) - .map((file) => ({ - originalname: file.originalname, - bufferBase64: file.buffer.toString("base64"), - })); - - const payload: SeleniumPayload = { - claim: claimData, - pdfs, - images, - }; - - const result = await axios.post( - "http://localhost:5002/eligibiliy-check", - payload - ); - if (result.data.status === "error") { - const errorMsg = - typeof result.data.message === "string" - ? result.data.message - : result.data.message?.msg || "Selenium agent error"; - throw new Error(errorMsg); - } - - return result.data; -} \ No newline at end of file diff --git a/apps/Backend/src/services/seleniumInsuranceEligibilityClient.ts b/apps/Backend/src/services/seleniumInsuranceEligibilityClient.ts new file mode 100644 index 0000000..7d9edb3 --- /dev/null +++ b/apps/Backend/src/services/seleniumInsuranceEligibilityClient.ts @@ -0,0 +1,27 @@ +import axios from "axios"; + +export interface SeleniumPayload { + data: any; +} + +export async function forwardToSeleniumInsuranceEligibilityAgent( + insuranceEligibilityData: any +): Promise { + const payload: SeleniumPayload = { + data: insuranceEligibilityData, + }; + + const result = await axios.post( + "http://localhost:5002/eligibility-check", + payload + ); + if (result.data.status === "error") { + const errorMsg = + typeof result.data.message === "string" + ? result.data.message + : result.data.message?.msg || "Selenium agent error"; + throw new Error(errorMsg); + } + + return result.data; +} diff --git a/apps/Frontend/src/components/claims/selenium-task-banner.tsx b/apps/Frontend/src/components/claims/selenium-task-banner.tsx index bf49a95..3346b2e 100644 --- a/apps/Frontend/src/components/claims/selenium-task-banner.tsx +++ b/apps/Frontend/src/components/claims/selenium-task-banner.tsx @@ -1,14 +1,15 @@ -import { useSelector, useDispatch } from "react-redux"; -import { RootState } from "@/redux/store"; -import { clearTaskStatus } from "@/redux/slices/seleniumTaskSlice"; import { Loader2, CheckCircle, XCircle } from "lucide-react"; -export const SeleniumTaskBanner = () => { - const { status, message, show } = useSelector( - (state: RootState) => state.seleniumTask - ); - const dispatch = useDispatch(); +export type TaskStatus = "idle" | "pending" | "success" | "error"; +interface Props { + status: TaskStatus; + message: string; + show: boolean; + onClear: () => void; +} + +export const SeleniumTaskBanner = ({ status, message, show, onClear }: Props) => { if (!show) return null; const getIcon = () => { @@ -33,14 +34,14 @@ export const SeleniumTaskBanner = () => { {status === "pending" ? "Selenium Task In Progress" : status === "success" - ? "Selenium Task Completed" - : "Selenium Task Error"} + ? "Selenium Task Completed" + : "Selenium Task Error"}

{message}