feat(eligibility-check) - enhance DDMA and DentaQuest workflows with flexible input handling; added detailed logging for patient data processing and eligibility status updates; improved browser cache management in Selenium service
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
NODE_ENV="development"
|
||||
HOST=0.0.0.0
|
||||
PORT=5000
|
||||
FRONTEND_URLS=http://localhost:3000,http://192.168.1.8:3000
|
||||
# FRONTEND_URLS=http://localhost:3000,http://192.168.1.8:3000
|
||||
FRONTEND_URLS=http://localhost:3000
|
||||
SELENIUM_AGENT_BASE_URL=http://localhost:5002
|
||||
JWT_SECRET = 'dentalsecret'
|
||||
DB_HOST=localhost
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=mypassword
|
||||
DB_NAME=dentalapp
|
||||
DATABASE_URL=postgresql://postgres:mypassword@localhost:5432/dentalapp
|
||||
DATABASE_URL=postgresql://postgres:mypassword@localhost:5432/dentalapp
|
||||
|
||||
@@ -41,7 +41,8 @@ function isOriginAllowed(origin?: string | null) {
|
||||
// Dev mode: allow localhost origins automatically
|
||||
if (
|
||||
origin.startsWith("http://localhost") ||
|
||||
origin.startsWith("http://127.0.0.1")
|
||||
origin.startsWith("http://127.0.0.1") ||
|
||||
origin.startsWith("http://192.168.0.238")
|
||||
)
|
||||
return true;
|
||||
// allow explicit FRONTEND_URLS if provided
|
||||
|
||||
@@ -136,36 +136,135 @@ async function handleDdmaCompletedJob(
|
||||
|
||||
// We'll wrap the processing in try/catch/finally so cleanup always runs
|
||||
try {
|
||||
// 1) ensuring memberid.
|
||||
const insuranceEligibilityData = job.insuranceEligibilityData;
|
||||
const insuranceId = String(insuranceEligibilityData.memberId ?? "").trim();
|
||||
|
||||
// DEBUG: Log the raw selenium result
|
||||
console.log(`[ddma-eligibility] === DEBUG: Raw seleniumResult ===`);
|
||||
console.log(`[ddma-eligibility] seleniumResult.patientName: '${seleniumResult?.patientName}'`);
|
||||
console.log(`[ddma-eligibility] seleniumResult.memberId: '${seleniumResult?.memberId}'`);
|
||||
console.log(`[ddma-eligibility] seleniumResult.status: '${seleniumResult?.status}'`);
|
||||
|
||||
// 1) Get insuranceId - prefer from Selenium result (flexible search support)
|
||||
let insuranceId = String(seleniumResult?.memberId || "").trim();
|
||||
if (!insuranceId) {
|
||||
throw new Error("Missing memberId for ddma job");
|
||||
insuranceId = String(insuranceEligibilityData.memberId ?? "").trim();
|
||||
}
|
||||
console.log(`[ddma-eligibility] Resolved insuranceId: ${insuranceId || "(none)"}`);
|
||||
|
||||
// 2) Create or update patient (with name from selenium result if available)
|
||||
// 2) Get patient name - prefer from Selenium result
|
||||
const patientNameFromResult =
|
||||
typeof seleniumResult?.patientName === "string"
|
||||
? seleniumResult.patientName.trim()
|
||||
: null;
|
||||
|
||||
console.log(`[ddma-eligibility] patientNameFromResult: '${patientNameFromResult}'`);
|
||||
|
||||
const { firstName, lastName } = splitName(patientNameFromResult);
|
||||
// Get name from input data as fallback
|
||||
let firstName = String(insuranceEligibilityData.firstName || "").trim();
|
||||
let lastName = String(insuranceEligibilityData.lastName || "").trim();
|
||||
|
||||
// Override with name from Selenium result if available
|
||||
if (patientNameFromResult) {
|
||||
const parsedName = splitName(patientNameFromResult);
|
||||
console.log(`[ddma-eligibility] splitName result: firstName='${parsedName.firstName}', lastName='${parsedName.lastName}'`);
|
||||
if (parsedName.firstName) firstName = parsedName.firstName;
|
||||
if (parsedName.lastName) lastName = parsedName.lastName;
|
||||
}
|
||||
console.log(`[ddma-eligibility] Resolved name: firstName='${firstName}', lastName='${lastName}'`);
|
||||
|
||||
await createOrUpdatePatientByInsuranceId({
|
||||
insuranceId,
|
||||
firstName,
|
||||
lastName,
|
||||
dob: insuranceEligibilityData.dateOfBirth,
|
||||
userId: job.userId,
|
||||
});
|
||||
|
||||
// 3) Update patient status + PDF upload
|
||||
const patient = await storage.getPatientByInsuranceId(
|
||||
insuranceEligibilityData.memberId
|
||||
);
|
||||
// 3) Find or create patient
|
||||
let patient: any = null;
|
||||
|
||||
// First, try to find by insuranceId if available
|
||||
if (insuranceId) {
|
||||
patient = await storage.getPatientByInsuranceId(insuranceId);
|
||||
if (patient) {
|
||||
console.log(`[ddma-eligibility] Found patient by insuranceId: ${patient.id}`);
|
||||
|
||||
// Update name if we have better data
|
||||
const updates: any = {};
|
||||
if (firstName && String(patient.firstName ?? "").trim() !== firstName) {
|
||||
updates.firstName = firstName;
|
||||
}
|
||||
if (lastName && String(patient.lastName ?? "").trim() !== lastName) {
|
||||
updates.lastName = lastName;
|
||||
}
|
||||
if (Object.keys(updates).length > 0) {
|
||||
await storage.updatePatient(patient.id, updates);
|
||||
console.log(`[ddma-eligibility] Updated patient name to: ${firstName} ${lastName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If not found by ID, try to find by name
|
||||
if (!patient && firstName && lastName) {
|
||||
try {
|
||||
console.log(`[ddma-eligibility] Looking up patient by name: ${firstName} ${lastName}`);
|
||||
const patients = await storage.getPatientsByUserId(job.userId);
|
||||
patient = patients.find(
|
||||
(p: any) =>
|
||||
String(p.firstName ?? "").toLowerCase() === firstName.toLowerCase() &&
|
||||
String(p.lastName ?? "").toLowerCase() === lastName.toLowerCase()
|
||||
) || null;
|
||||
if (patient) {
|
||||
console.log(`[ddma-eligibility] Found patient by name: ${patient.id}`);
|
||||
// Update insuranceId if we have it
|
||||
if (insuranceId && String(patient.insuranceId ?? "").trim() !== insuranceId) {
|
||||
await storage.updatePatient(patient.id, { insuranceId });
|
||||
console.log(`[ddma-eligibility] Updated patient insuranceId to: ${insuranceId}`);
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.log(`[ddma-eligibility] Error finding patient by name: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine eligibility status from Selenium result
|
||||
const eligibilityStatus = seleniumResult.eligibility === "active" ? "ACTIVE" : "INACTIVE";
|
||||
console.log(`[ddma-eligibility] Eligibility status from Delta MA: ${eligibilityStatus}`);
|
||||
|
||||
// If still not found, create new patient
|
||||
console.log(`[ddma-eligibility] Patient creation check: patient=${patient?.id || 'null'}, firstName='${firstName}', lastName='${lastName}'`);
|
||||
if (!patient && firstName && lastName) {
|
||||
console.log(`[ddma-eligibility] Creating new patient: ${firstName} ${lastName} with status: ${eligibilityStatus}`);
|
||||
try {
|
||||
let parsedDob: Date | undefined = undefined;
|
||||
if (insuranceEligibilityData.dateOfBirth) {
|
||||
try {
|
||||
parsedDob = new Date(insuranceEligibilityData.dateOfBirth);
|
||||
if (isNaN(parsedDob.getTime())) parsedDob = undefined;
|
||||
} catch {
|
||||
parsedDob = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const newPatientData: InsertPatient = {
|
||||
firstName,
|
||||
lastName,
|
||||
dateOfBirth: parsedDob || new Date(), // Required field
|
||||
insuranceId: insuranceId || undefined,
|
||||
insuranceProvider: "Delta MA", // Set insurance provider
|
||||
gender: "Unknown", // Required field - default value
|
||||
phone: "", // Required field - default empty
|
||||
userId: job.userId, // Required field
|
||||
status: eligibilityStatus, // Set status from eligibility check
|
||||
};
|
||||
|
||||
const validation = insertPatientSchema.safeParse(newPatientData);
|
||||
if (validation.success) {
|
||||
patient = await storage.createPatient(validation.data);
|
||||
console.log(`[ddma-eligibility] Created new patient: ${patient.id} with status: ${eligibilityStatus}`);
|
||||
} else {
|
||||
console.log(`[ddma-eligibility] Patient validation failed: ${validation.error.message}`);
|
||||
}
|
||||
} catch (createErr: any) {
|
||||
console.log(`[ddma-eligibility] Failed to create patient: ${createErr.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!patient?.id) {
|
||||
outputResult.patientUpdateStatus =
|
||||
"Patient not found; no update performed";
|
||||
"Patient not found and could not be created; no update performed";
|
||||
return {
|
||||
patientUpdateStatus: outputResult.patientUpdateStatus,
|
||||
pdfUploadStatus: "none",
|
||||
@@ -173,11 +272,10 @@ async function handleDdmaCompletedJob(
|
||||
};
|
||||
}
|
||||
|
||||
// update patient status.
|
||||
const newStatus =
|
||||
seleniumResult.eligibility === "active" ? "ACTIVE" : "INACTIVE";
|
||||
await storage.updatePatient(patient.id, { status: newStatus });
|
||||
outputResult.patientUpdateStatus = `Patient status updated to ${newStatus}`;
|
||||
// Update patient status from Delta MA eligibility result
|
||||
await storage.updatePatient(patient.id, { status: eligibilityStatus });
|
||||
outputResult.patientUpdateStatus = `Patient ${patient.id} status set to ${eligibilityStatus} (Delta MA eligibility: ${seleniumResult.eligibility})`;
|
||||
console.log(`[ddma-eligibility] ${outputResult.patientUpdateStatus}`);
|
||||
|
||||
// Handle PDF or convert screenshot -> pdf if available
|
||||
let pdfBuffer: Buffer | null = null;
|
||||
|
||||
@@ -200,9 +200,13 @@ async function handleDentaQuestCompletedJob(
|
||||
}
|
||||
}
|
||||
|
||||
// Determine eligibility status from Selenium result
|
||||
const eligibilityStatus = seleniumResult.eligibility === "active" ? "ACTIVE" : "INACTIVE";
|
||||
console.log(`[dentaquest-eligibility] Eligibility status from DentaQuest: ${eligibilityStatus}`);
|
||||
|
||||
// If still no patient found, CREATE a new one with the data we have
|
||||
if (!patient?.id && firstName && lastName) {
|
||||
console.log(`[dentaquest-eligibility] Creating new patient: ${firstName} ${lastName}`);
|
||||
console.log(`[dentaquest-eligibility] Creating new patient: ${firstName} ${lastName} with status: ${eligibilityStatus}`);
|
||||
|
||||
const createPayload: any = {
|
||||
firstName,
|
||||
@@ -212,6 +216,8 @@ async function handleDentaQuestCompletedJob(
|
||||
phone: "",
|
||||
userId: job.userId,
|
||||
insuranceId: insuranceId || null,
|
||||
insuranceProvider: "DentaQuest", // Set insurance provider
|
||||
status: eligibilityStatus, // Set status from eligibility check
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -219,7 +225,7 @@ async function handleDentaQuestCompletedJob(
|
||||
const newPatient = await storage.createPatient(patientData);
|
||||
if (newPatient) {
|
||||
patient = newPatient;
|
||||
console.log(`[dentaquest-eligibility] Created new patient with ID: ${patient.id}`);
|
||||
console.log(`[dentaquest-eligibility] Created new patient with ID: ${patient.id}, status: ${eligibilityStatus}`);
|
||||
}
|
||||
} catch (err: any) {
|
||||
// Try without dateOfBirth if it fails
|
||||
@@ -230,7 +236,7 @@ async function handleDentaQuestCompletedJob(
|
||||
const newPatient = await storage.createPatient(patientData);
|
||||
if (newPatient) {
|
||||
patient = newPatient;
|
||||
console.log(`[dentaquest-eligibility] Created new patient (no DOB) with ID: ${patient.id}`);
|
||||
console.log(`[dentaquest-eligibility] Created new patient (no DOB) with ID: ${patient.id}, status: ${eligibilityStatus}`);
|
||||
}
|
||||
} catch (err2: any) {
|
||||
console.error(`[dentaquest-eligibility] Failed to create patient: ${err2?.message}`);
|
||||
@@ -248,11 +254,10 @@ async function handleDentaQuestCompletedJob(
|
||||
};
|
||||
}
|
||||
|
||||
// update patient status.
|
||||
const newStatus =
|
||||
seleniumResult.eligibility === "active" ? "ACTIVE" : "INACTIVE";
|
||||
await storage.updatePatient(patient.id, { status: newStatus });
|
||||
outputResult.patientUpdateStatus = `Patient status updated to ${newStatus}`;
|
||||
// Update patient status from DentaQuest eligibility result
|
||||
await storage.updatePatient(patient.id, { status: eligibilityStatus });
|
||||
outputResult.patientUpdateStatus = `Patient ${patient.id} status set to ${eligibilityStatus} (DentaQuest eligibility: ${seleniumResult.eligibility})`;
|
||||
console.log(`[dentaquest-eligibility] ${outputResult.patientUpdateStatus}`);
|
||||
|
||||
// Handle PDF or convert screenshot -> pdf if available
|
||||
let pdfBuffer: Buffer | null = null;
|
||||
|
||||
Reference in New Issue
Block a user