feat: route batch-column claims by insurance type, fix eligibility UX

- claims.ts: batch-column now routes each patient to the correct portal
  (MH/CCA/DDMA/TuftsSCO/UnitedSCO) based on patient.insuranceProvider
- appointments-page.tsx: eligibility badge falls back to patientStatus
  for all insurance types, not just MassHealth
- unitedDHClaimProcessor/ddmaClaimProcessor/tuftsSCOClaimProcessor:
  auto-save claim PDF when no socketId (batch-column path)
- unitedSCOEligibilityProcessor: unknown eligibility no longer stored as INACTIVE
- queues.ts: add tuftssco-claim-submit and uniteddh-claim-submit to SeleniumJobType
- selenium_UnitedSCO_eligibilityCheckWorker.py:
  - step1: add Select Insurance OK click with staleness wait; Provider &
    Location page just clicks Continue; skip first/last name input
  - step2: extract name from eligibility details tab (ALL CAPS → title case);
    skip "not available" guard; fix name regex to match only all-caps words
- .gitignore: ignore all chrome_profile_* directories

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ff
2026-05-27 23:07:42 -04:00
parent 1b017177e9
commit 3e61bdec36
261 changed files with 331 additions and 119284 deletions

View File

@@ -14,6 +14,8 @@ import {
} from "../../services/seleniumDDMAClaimClient";
import { io } from "../../socket";
import { storage } from "../../storage";
import axios from "axios";
import path from "path";
function log(tag: string, msg: string, ctx?: any) {
console.log(`${new Date().toISOString()} [${tag}] ${msg}`, ctx ?? "");
@@ -86,6 +88,21 @@ async function pollUntilDone(
throw new Error(`DDMA claim polling exhausted all attempts for session ${sessionId}`);
}
async function savePdfFromSelenium(pdf_url: string, patientId: number) {
try {
const filename = path.basename(new URL(pdf_url).pathname);
const seleniumPort = process.env.SELENIUM_PORT || "5002";
const localUrl = `http://localhost:${seleniumPort}/downloads/${filename}`;
const resp = await axios.get(localUrl, { responseType: "arraybuffer", timeout: 30000 });
let group = await storage.findPdfGroupByPatientTitleKey(patientId, "INSURANCE_CLAIM");
if (!group) group = await storage.createPdfGroup(patientId, "Claims", "INSURANCE_CLAIM");
await storage.createPdfFile(group.id!, filename, resp.data);
log("ddma-claim-processor", "PDF saved", { patientId, filename });
} catch (err: any) {
log("ddma-claim-processor", "failed to save PDF (non-fatal)", { error: err?.message ?? err });
}
}
export interface DDMAClaimProcessorInput {
enrichedPayload: any;
userId: number;
@@ -139,6 +156,13 @@ export async function runDDMAClaimProcessor(
}
}
// Auto-save PDF for batch-column calls (no socketId = no frontend listener)
if (pdf_url && !socketId) {
const claim = claimId ? await storage.getClaim(claimId).catch(() => null) : null;
const patientId = claim?.patientId ?? enrichedPayload?.claim?.patientId ?? enrichedPayload?.patientId;
if (patientId) await savePdfFromSelenium(pdf_url, Number(patientId));
}
emitToSocket(socketId, "selenium:ddma_claim_completed", {
jobId,
claimId,

View File

@@ -14,6 +14,8 @@ import {
} from "../../services/seleniumTuftsSCOClaimClient";
import { io } from "../../socket";
import { storage } from "../../storage";
import axios from "axios";
import path from "path";
function log(tag: string, msg: string, ctx?: any) {
console.log(`${new Date().toISOString()} [${tag}] ${msg}`, ctx ?? "");
@@ -85,6 +87,21 @@ async function pollUntilDone(
throw new Error(`Tufts SCO claim polling exhausted all attempts for session ${sessionId}`);
}
async function savePdfFromSelenium(pdf_url: string, patientId: number) {
try {
const filename = path.basename(new URL(pdf_url).pathname);
const seleniumPort = process.env.SELENIUM_PORT || "5002";
const localUrl = `http://localhost:${seleniumPort}/downloads/${filename}`;
const resp = await axios.get(localUrl, { responseType: "arraybuffer", timeout: 30000 });
let group = await storage.findPdfGroupByPatientTitleKey(patientId, "INSURANCE_CLAIM");
if (!group) group = await storage.createPdfGroup(patientId, "Claims", "INSURANCE_CLAIM");
await storage.createPdfFile(group.id!, filename, resp.data);
log("tuftssco-claim-processor", "PDF saved", { patientId, filename });
} catch (err: any) {
log("tuftssco-claim-processor", "failed to save PDF (non-fatal)", { error: err?.message ?? err });
}
}
export interface TuftsSCOClaimProcessorInput {
enrichedPayload: any;
userId: number;
@@ -130,6 +147,13 @@ export async function runTuftsSCOClaimProcessor(
}
}
// Auto-save PDF for batch-column calls (no socketId = no frontend listener)
if (pdf_url && !socketId) {
const claim = claimId ? await storage.getClaim(claimId).catch(() => null) : null;
const patientId = claim?.patientId ?? enrichedPayload?.claim?.patientId ?? enrichedPayload?.patientId;
if (patientId) await savePdfFromSelenium(pdf_url, Number(patientId));
}
emitToSocket(socketId, "selenium:tuftssco_claim_completed", {
jobId,
claimId,

View File

@@ -14,6 +14,8 @@ import {
} from "../../services/seleniumUnitedDHClaimClient";
import { io } from "../../socket";
import { storage } from "../../storage";
import axios from "axios";
import path from "path";
function log(tag: string, msg: string, ctx?: any) {
console.log(`${new Date().toISOString()} [${tag}] ${msg}`, ctx ?? "");
@@ -97,6 +99,24 @@ async function pollUntilDone(
throw new Error(`UnitedDH claim polling exhausted all attempts for session ${sessionId}`);
}
async function savePdfFromSelenium(pdf_url: string, patientId: number) {
try {
const filename = path.basename(new URL(pdf_url).pathname);
const seleniumPort = process.env.SELENIUM_PORT || "5002";
const localUrl = `http://localhost:${seleniumPort}/downloads/${filename}`;
const resp = await axios.get(localUrl, { responseType: "arraybuffer", timeout: 30000 });
let group = await storage.findPdfGroupByPatientTitleKey(patientId, "INSURANCE_CLAIM");
if (!group) {
group = await storage.createPdfGroup(patientId, "Claims", "INSURANCE_CLAIM");
}
await storage.createPdfFile(group.id!, filename, resp.data);
log("uniteddh-claim-processor", "PDF saved", { patientId, filename });
} catch (err: any) {
log("uniteddh-claim-processor", "failed to save PDF (non-fatal)", { error: err?.message ?? err });
}
}
export interface UnitedDHClaimProcessorInput {
enrichedPayload: any;
userId: number;
@@ -149,6 +169,13 @@ export async function runUnitedDHClaimProcessor(
}
}
// Auto-save PDF for batch-column calls (no socketId = no frontend listener)
if (pdf_url && !socketId) {
const claim = claimId ? await storage.getClaim(claimId).catch(() => null) : null;
const patientId = claim?.patientId ?? enrichedPayload?.claim?.patientId ?? enrichedPayload?.patientId;
if (patientId) await savePdfFromSelenium(pdf_url, Number(patientId));
}
emitToSocket(socketId, "selenium:uniteddh_claim_completed", {
jobId,
claimId,

View File

@@ -104,13 +104,21 @@ async function processUnitedSCOResult(
// 4) Determine eligibility status
const eligStatus = (seleniumResult?.eligibility ?? "").toLowerCase();
const newStatus = eligStatus === "active" || eligStatus === "y" ? "ACTIVE" : "INACTIVE";
const newStatus =
eligStatus === "active" || eligStatus === "y" ? "ACTIVE" :
eligStatus === "inactive" ? "INACTIVE" : null;
await storage.updatePatient(patient.id, {
status: newStatus,
insuranceProvider: "United Healthcare SCO",
});
output.patientUpdateStatus = `Patient status updated to ${newStatus}`;
if (newStatus) {
await storage.updatePatient(patient.id, {
status: newStatus,
insuranceProvider: "United Healthcare SCO",
});
output.patientUpdateStatus = `Patient status updated to ${newStatus}`;
} else {
// Unknown eligibility — still update insuranceProvider but leave status unchanged
await storage.updatePatient(patient.id, { insuranceProvider: "United Healthcare SCO" });
output.patientUpdateStatus = `Eligibility unknown — status not changed`;
}
// 5) Resolve PDF buffer from file path (same as DDMA)
let pdfBuffer: Buffer | null = null;

View File

@@ -14,6 +14,8 @@ export type SeleniumJobType =
| "cca-claim-submit"
| "cca-preauth-submit"
| "ddma-claim-submit"
| "tuftssco-claim-submit"
| "uniteddh-claim-submit"
| "tuftssco-eligibility-check"
| "mh-eligibility-history-check"
| "cmsp-eligibility-history-remaining-check";

View File

@@ -9,6 +9,7 @@ import fs from "fs";
import axios from "axios";
import archiver from "archiver";
import { seleniumQueue } from "../queue/queues";
import { enqueueSeleniumJob } from "../queue/jobRunner";
import { Prisma } from "@repo/db/generated/prisma";
import { Decimal } from "decimal.js";
import {
@@ -415,6 +416,28 @@ router.post(
}
);
// Maps patient.insuranceProvider free-text → the siteKey stored in InsuranceCredential
function batchColumnDeriveSiteKey(provider: string): string {
const p = provider.toLowerCase().trim();
if (!p || p.includes("masshealth") || p === "mh" || p === "mass health") return "MH";
if (p.includes("commonwealth care alliance") || p === "cca") return "CCA";
if (p.includes("ddma") || p.includes("delta dental ma")) return "DDMA";
if (p.includes("tufts") || p.includes("dentaquest") || p === "tuftssco") return "TUFTS_SCO";
if ((p.includes("united") && p.includes("sco")) || p.includes("dentalhub") || p === "united_sco") return "UNITED_SCO";
return "MH"; // default fallback
}
// Returns the canonical insuranceProvider name stored in the Claim record
function batchColumnCanonicalName(siteKey: string): string {
switch (siteKey) {
case "CCA": return "CCA";
case "DDMA": return "Delta Dental MA";
case "TUFTS_SCO": return "Tufts SCO";
case "UNITED_SCO": return "United/DentalHub";
default: return "MassHealth";
}
}
// POST /api/claims/batch-column
// Query params: date=YYYY-MM-DD (required), staffIds=1,2 (required)
// For each appointment in the selected staff columns:
@@ -555,10 +578,15 @@ router.post(
continue;
}
// MassHealth credentials
const credentials = await storage.getInsuranceCredentialByUserAndSiteKey(req.user.id, "MH");
// Always derive siteKey from the patient record — claim.insuranceProvider
// may be stale (e.g. previously set to "MassHealth" by the old hardcoded path)
const rawInsuranceProvider = (patient.insuranceProvider ?? "").trim();
const siteKey = batchColumnDeriveSiteKey(rawInsuranceProvider);
const canonicalInsuranceProvider = batchColumnCanonicalName(siteKey);
const credentials = await storage.getInsuranceCredentialByUserAndSiteKey(req.user.id, siteKey);
if (!credentials) {
resultItem.error = "No MassHealth credentials found — check Settings";
resultItem.error = `No ${canonicalInsuranceProvider} credentials found — check Settings`;
results.push(resultItem);
continue;
}
@@ -573,7 +601,7 @@ router.post(
// Priority: Select Procedures choice > existing claim > first provider
const claimNpiProviderId = procNpiProviderId ?? activeClaim?.npiProviderId ?? npiProvider?.id ?? null;
console.log(`[batch-column] apt=${apt.id} procNpiId=${procNpiProviderId} claimNpiId=${activeClaim?.npiProviderId} resolved=${claimNpiProviderId}`);
console.log(`[batch-column] apt=${apt.id} siteKey=${siteKey} procNpiId=${procNpiProviderId} claimNpiId=${activeClaim?.npiProviderId} resolved=${claimNpiProviderId}`);
const patientName = `${patient.firstName ?? ""} ${patient.lastName ?? ""}`.trim();
@@ -597,7 +625,7 @@ router.post(
? Number(claimNpiProviderId)
: null;
console.log(`[batch-column] creating claim: patientId=${patient.id} aptId=${apt.id} staffId=${safeStaffId} npiProviderId=${safeNpiId} serviceDate=${serviceDate} dobStr=${dobStr} lines=${serviceLines.length}`);
console.log(`[batch-column] creating claim: patientId=${patient.id} aptId=${apt.id} staffId=${safeStaffId} npiProviderId=${safeNpiId} serviceDate=${serviceDate} dobStr=${dobStr} lines=${serviceLines.length} insurance=${canonicalInsuranceProvider}`);
const newClaim = await storage.createClaim({
patientId: Number(patient.id),
@@ -608,7 +636,7 @@ router.post(
memberId,
dateOfBirth: new Date(dobStr),
serviceDate: new Date(serviceDate),
insuranceProvider: "MassHealth",
insuranceProvider: canonicalInsuranceProvider,
remarks: "",
missingTeethStatus: "No_missing",
missingTeeth: {},
@@ -643,33 +671,6 @@ router.post(
if (saved) resolvedNpiProvider = saved;
}
// Build enriched payload for selenium
const enrichedPayload: any = {
patientId: Number(patient.id),
appointmentId: Number(apt.id),
userId: req.user.id,
staffId: Number(apt.staffId),
patientName,
memberId,
dateOfBirth: dobStr,
serviceDate,
insuranceProvider: "MassHealth",
insuranceSiteKey: "MH",
missingTeethStatus: activeClaim?.missingTeethStatus ?? "No_missing",
missingTeeth: activeClaim?.missingTeeth ?? {},
remarks: activeClaim?.remarks ?? "",
serviceLines,
claimId,
massdhpUsername: credentials.username,
massdhpPassword: credentials.password,
};
if (resolvedNpiProvider) {
enrichedPayload.npiProvider = {
npiNumber: resolvedNpiProvider.npiNumber,
providerName: resolvedNpiProvider.providerName,
};
}
// Collect attachments: appointment-level files + claim-level files
const apptFiles = await storage.getAppointmentFiles(Number(apt.id));
const claimFiles = (activeClaim as any)?.claimFiles ?? [];
@@ -689,17 +690,120 @@ router.post(
return [{ originalname: f.filename, bufferBase64, mimetype: f.mimeType ?? "application/octet-stream" }];
});
// Enqueue selenium claim-submit job
const job = await seleniumQueue.add("claim-submit", {
jobType: "claim-submit",
// Base claim data shared across all insurance pathways
const baseClaimPayload: any = {
patientId: Number(patient.id),
appointmentId: Number(apt.id),
userId: req.user.id,
enrichedPayload,
files: filesForQueue,
staffId: Number(apt.staffId),
patientName,
memberId,
dateOfBirth: dobStr,
serviceDate,
missingTeethStatus: activeClaim?.missingTeethStatus ?? "No_missing",
missingTeeth: activeClaim?.missingTeeth ?? {},
remarks: activeClaim?.remarks ?? "",
serviceLines,
claimId,
});
...(resolvedNpiProvider ? {
npiProvider: {
npiNumber: resolvedNpiProvider.npiNumber,
providerName: resolvedNpiProvider.providerName,
},
} : {}),
};
// Enqueue to the correct insurance pathway
let jobId: string;
if (siteKey === "MH") {
const enrichedPayload = {
...baseClaimPayload,
insuranceProvider: "MassHealth",
insuranceSiteKey: "MH",
massdhpUsername: credentials.username,
massdhpPassword: credentials.password,
};
const job = await seleniumQueue.add("claim-submit", {
jobType: "claim-submit",
userId: req.user.id,
enrichedPayload,
files: filesForQueue,
claimId,
});
jobId = String(job.id);
} else if (siteKey === "CCA") {
const enrichedPayload = {
claim: {
...baseClaimPayload,
insuranceProvider: "CCA",
insuranceSiteKey: "CCA",
cca_username: credentials.username,
cca_password: credentials.password,
},
files: filesForQueue,
};
jobId = enqueueSeleniumJob({
jobType: "cca-claim-submit",
userId: req.user.id,
enrichedPayload,
claimId,
});
} else if (siteKey === "DDMA") {
const enrichedPayload = {
claim: {
...baseClaimPayload,
insuranceProvider: "Delta Dental MA",
insuranceSiteKey: "DDMA",
massddmaUsername: credentials.username,
massddmaPassword: credentials.password,
},
};
jobId = enqueueSeleniumJob({
jobType: "ddma-claim-submit",
userId: req.user.id,
enrichedPayload,
claimId,
});
} else if (siteKey === "TUFTS_SCO") {
const enrichedPayload = {
claim: {
...baseClaimPayload,
insuranceProvider: "Tufts SCO",
insuranceSiteKey: "TuftsSCO",
dentaquestUsername: credentials.username,
dentaquestPassword: credentials.password,
},
};
jobId = enqueueSeleniumJob({
jobType: "tuftssco-claim-submit",
userId: req.user.id,
enrichedPayload,
claimId,
});
} else if (siteKey === "UNITED_SCO") {
const enrichedPayload = {
claim: {
...baseClaimPayload,
insuranceProvider: "United/DentalHub",
insuranceSiteKey: "UNITED_SCO",
uniteddhUsername: credentials.username,
uniteddhPassword: credentials.password,
},
};
jobId = enqueueSeleniumJob({
jobType: "uniteddh-claim-submit",
userId: req.user.id,
enrichedPayload,
claimId,
});
} else {
resultItem.error = `Unsupported insurance type: ${siteKey}`;
results.push(resultItem);
continue;
}
resultItem.processed = true;
resultItem.jobId = String(job.id);
resultItem.jobId = jobId;
} catch (aptErr: any) {
console.error("[batch-column] apt error:", aptErr);

View File

@@ -107,8 +107,7 @@ function appointmentCardColor(apt: ScheduledAppointment): string {
function resolveAppointmentBadgeStatus(apt: ScheduledAppointment): PatientStatus {
if (apt.eligibilityStatus === "ACTIVE") return "ACTIVE";
if (apt.eligibilityStatus === "INACTIVE") return "INACTIVE";
const isMassHealth = apt.patientInsuranceProvider?.toLowerCase().includes("masshealth");
if (apt.eligibilityStatus === "UNKNOWN" && isMassHealth) {
if (apt.eligibilityStatus === "UNKNOWN") {
if (apt.patientStatus === "ACTIVE") return "ACTIVE";
if (apt.patientStatus === "INACTIVE") return "INACTIVE";
}

View File

@@ -1,2 +1,9 @@
.env
/__pycache__
/__pycache__
**/__pycache__
.last_credentials
chrome_profile_unitedsco/
chrome_profile_ddma/
chrome_profile_dentaquest/
chrome_profile_masshealth/
chrome_profile_*/

View File

@@ -1 +0,0 @@
[{"description":"treehash per file","signed_content":{"payload":"eyJjb250ZW50X2hhc2hlcyI6W3siYmxvY2tfc2l6ZSI6NDA5NiwiZGlnZXN0Ijoic2hhMjU2IiwiZmlsZXMiOlt7InBhdGgiOiJsaXN0ZGF0YS5qc29uIiwicm9vdF9oYXNoIjoiNmVJUlZmTTczUDJjbUxncUQ0UkRQMjU3a0Q5bWY1WUZscHlpREw1dUlfMCJ9LHsicGF0aCI6Im1hbmlmZXN0Lmpzb24iLCJyb290X2hhc2giOiItVlJhUzl1Q2xpeFJaSWR2c0VWMkxJb1l4UDREZHl1NTdUQUVfbUJ1dXBVIn1dLCJmb3JtYXQiOiJ0cmVlaGFzaCIsImhhc2hfYmxvY2tfc2l6ZSI6NDA5Nn1dLCJpdGVtX2lkIjoibmlub2RhYmNlanBlZ2xmamJraGRwbGFvZ2xwY2JmZmoiLCJpdGVtX3ZlcnNpb24iOiI4LjYyOTQuMjA1NyIsInByb3RvY29sX3ZlcnNpb24iOjF9","signatures":[{"header":{"kid":"publisher"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"jKit53qyELKtZdFmhNfr8UG21np9jbaiQqVos_AwfKv4_BgX2rGr9tFMYcixECPW2jWz3p_EXucBLRMppysx4tREaZvl9EEIh5rQOs4staXL4VU6ErcZemFbtGSoxxZIXi1xyIIliTA-qt1lzY_I5IrHjMMvCJCYlcElCyXxBseJ4qR0Ow9_VQqkaI9zIliBWVIAOt6c_-dL2hTkqoYCeXzIvqO4_0ui4wcj5WCAujTOc-zBl6WJeVZKtpc6_B5XI7flkjUnu5lGabghojB-Qc9Y-Fm1qZOz0zJPPj26EdqCMnyMpgDxssZyjO4P46Jjc_yMCXcKLpj5XmfoO1wRtScZPn3o4PSSVew305puVe2xJF-IhsbGSR1BWbRyMoQ0sCZkJC3VLdtW_w-emgNhgAGje-SwfkPckDe_vkrPpN6Rti_6J-SizkBUHDJMG-Dbl--_iiWOa_GwGvZx84WkWHxDRbkrhrGjgQcpXbrVtuZe8Fsx305sRj5qq5hxhlbguX_wYTK3Q_L7NjNHIkjOv6BuMF1Jo1EnCM1ey_PBx7z9pkZfRcHrCVhanvfpaXk_GeAuog1H5ESWetFgGuyvFjgApgPUycfo7c23bPIVMitpn8n1kjmUk7q11mzZANESmtDOQGDRlzhTXck6UC9DDP-AgbOMVryMRUS3MKxI58w"},{"header":{"kid":"webstore"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"Eh7dVhKTBXsgvpNfC3nIXqJpMFzZD9oXTcm9024Z8zEOFSEw1nHWGU4Yrg_4wCpb2EiSFg9aXcVH9GvpeGg0EcGKbozMqwwmYk8UlOU5jpMf7B-afAFFKngNCuyDThtcWvWY6oKEJSVN7V4NcQ1dfhhxZLCfI8wqTbzEWCDS5vTuG0qZBHtkH4-d7r7W3c8ey4V0HtboOSF7FbHm5pC9x6T-e1uqmU0Ek-0pfHyYh-RYENVKZJN9-w8JF4y5KNN08Cyrn3-GB4IbJ6U7tgwCFnbpQqAr9oSeEcXitN0NmKuKySzvuVdNh_jQdgAOf5fkajDXHdxAWyaU1AErMLrTqQ"}]}}]

View File

@@ -1,5 +0,0 @@
{
"manifest_version": 2,
"name": "listdata.json",
"version": "8.6294.2057"
}

View File

@@ -1 +0,0 @@
[{"description":"treehash per file","signed_content":{"payload":"eyJjb250ZW50X2hhc2hlcyI6W3siYmxvY2tfc2l6ZSI6NDA5NiwiZGlnZXN0Ijoic2hhMjU2IiwiZmlsZXMiOlt7InBhdGgiOiJoZXVyaXN0aWNfcmVnZXhlcy5iaW5hcnlwYiIsInJvb3RfaGFzaCI6Im9ROWwxLURWWndMVzhJaFF5TDdwdlZHdkZfUy1CUmtBX3l1SXlTRi1RbDgifSx7InBhdGgiOiJtYW5pZmVzdC5qc29uIiwicm9vdF9oYXNoIjoibGFLd2RJdXU1d2RBX3kxZHA0LVl0YUtaVUZZdm1KV1I4TEMxdnhNMVM0VSJ9XSwiZm9ybWF0IjoidHJlZWhhc2giLCJoYXNoX2Jsb2NrX3NpemUiOjQwOTZ9XSwiaXRlbV9pZCI6Imhhamlnb3BiYmpoZ2hiZmltZ2tmbXBlbmZrY2xtb2hrIiwiaXRlbV92ZXJzaW9uIjoiNCIsInByb3RvY29sX3ZlcnNpb24iOjF9","signatures":[{"header":{"kid":"publisher"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"mqnzWWPXdMmUXubyqBppOqxAY921JfSOK_NcvIfwW7mkskMg4BQz9pzkrCPEJkJVcG_XUzkx1ByskF-ZC03s0RRaghvq-xYyFIOeL8g1A6wge9NuIZiD_KGIFmjieufISG8gijhKXINUgo6aKiGVQXWlMIRluSkGYmcTDeGW87JI1CkybIDjk3BOyKewFQiPDoafqe0BtW6fW8904q-C4xrrQHyCbmOjqhmO4VIusYh3J_LA4so-B3O-nVC30XaISnRKYPDTQzsTkz_eJq9LJcPL5RORZUrRaiDLMINSJaOUtne_6CT-6tlEuaZdLpeL9oIIsAc6taHZsz8yJvHhaVnjQsXL6eJrBufupTRY5i_Q0ir_aAsiBIu5xcOirAeMknUhxmFCGW5h7xEdp-FBL2d4ukbSDhlv2qrhPzd0TjNshQoXBaZSvLVjv9sC4RSF4vwva8j9O81ZfmFyyyzBs_mYsM0cMrrRETTXg_KrYiF-CSYBM3cZQWFyJ-w_-G0kRiryB0tG9AYkDAo2DcPuHAO7pRibl7CwM9mxsD4SFjiN_dlPUfMHBUGhgPZofVb2c7nY7ztndNKPzNKwYOZLrhj8G6-TQgJL7QplhG761mrkUrZOGzAIBu8i4HN9SqfFIClGNjLYdmXruTveYMQV0RwO--7HT4Dvd2OEwa5shsw"},{"header":{"kid":"webstore"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"CG6KXxg_Mpqgw7XcrysRHH5F6HAql4JmenqcSzsnyja8z2d_cW6IfuHAmBQ78gE8HGIa4RUC3JQn08MN5zH2PlLfo4Lnr6NOyQGatRN7PZyK6gzaIMhK_0-CVEHR-A2mP9JpT9ksmxcURiKpAK44fTqod2KpzJMILYEFnB11MsZSEVYMYWQqT1mq4gRqo0uBne6paqZXKxLXIorweRX2KYPMYX9tHFt8CugLW5LmKPbReIJ4XJaLhLxRCHimnKtqx4r1_y7xPfitVCHIAfM5QVY6hv3xubPN2_bIPMeI6k2IlCZAH2tRptGgm9a80KlDpNQxMd9Eqi_z246ltVL2iA"}]}}]

View File

@@ -1,3 +0,0 @@
<EFBFBD>
<EFBFBD>(?:US\$|USD|\$)\s*\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?(?:\s*)(?:USD|US\$|\$)?|(?:USD|US\$|\$)?\s*\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?\s*(?:USD|US\$|\$)<12>^(?:\s*)(Due now \(USD\)|(Estimated )?(?:Order Total|Total:?)|TOTAL CHARGED TODAY \*|Final Total Price:|Flight total|grand total:?|Order Total(?: \(USD\))?:?|Price|Total(?:(?: \(USD\))?| Due| for Stay| Price| to be paid:| to pay|:)?|(Your )?(?:Payment Today|total(\s)price|Total:)|Show Order Summary:|Reservation Deposit Amount Due|Payment Due Now|Your Price|Total Due Now|Amount to pay|Total amount due|You pay today|Order Summary|TOTAL PAYMENT DUE|Payable Amount)(?:\s*)$

View File

@@ -1,5 +0,0 @@
{
"manifest_version": 2,
"name": "Amount Extraction Heuristic Regexes",
"version": "4"
}

View File

@@ -1,12 +0,0 @@
{
"epochs": [ {
"calculation_time": "13420944458137194",
"config_version": 0,
"model_version": "0",
"padded_top_topics_start_index": 0,
"taxonomy_version": 0,
"top_topics_and_observing_domains": [ ]
} ],
"hex_encoded_hmac_key": "24AD0CEEC0277EA6C3A355C732190B3C481360D7BE0EC4B7BA1282A9D36C1DAA",
"next_scheduled_calculation_time": "13421549258144341"
}

View File

@@ -1,2 +0,0 @@
2026/04/17-20:07:31.575 120577 Creating DB /home/ee/Desktop/Gitead-DentalManagementMHnewff/apps/SeleniumService/chrome_profile_dentaquest/Default/Extension Rules since it was missing.
2026/04/17-20:07:31.606 120577 Reusing MANIFEST /home/ee/Desktop/Gitead-DentalManagementMHnewff/apps/SeleniumService/chrome_profile_dentaquest/Default/Extension Rules/MANIFEST-000001

View File

@@ -1,2 +0,0 @@
2026/04/17-20:07:31.607 120577 Creating DB /home/ee/Desktop/Gitead-DentalManagementMHnewff/apps/SeleniumService/chrome_profile_dentaquest/Default/Extension Scripts since it was missing.
2026/04/17-20:07:31.637 120577 Reusing MANIFEST /home/ee/Desktop/Gitead-DentalManagementMHnewff/apps/SeleniumService/chrome_profile_dentaquest/Default/Extension Scripts/MANIFEST-000001

View File

@@ -1,3 +0,0 @@
2026/04/17-23:41:41.932 9b79 Reusing MANIFEST /home/ee/Desktop/Gitead-DentalManagementMHnewff/apps/SeleniumService/chrome_profile_dentaquest/Default/Extension State/MANIFEST-000001
2026/04/17-23:41:41.932 9b79 Recovering log #3
2026/04/17-23:41:41.932 9b79 Reusing old log /home/ee/Desktop/Gitead-DentalManagementMHnewff/apps/SeleniumService/chrome_profile_dentaquest/Default/Extension State/000003.log

View File

@@ -1,3 +0,0 @@
2026/04/17-23:41:47.142 9b8d Reusing MANIFEST /home/ee/Desktop/Gitead-DentalManagementMHnewff/apps/SeleniumService/chrome_profile_dentaquest/Default/GCM Store/MANIFEST-000001
2026/04/17-23:41:47.143 9b8d Recovering log #3
2026/04/17-23:41:47.143 9b8d Reusing old log /home/ee/Desktop/Gitead-DentalManagementMHnewff/apps/SeleniumService/chrome_profile_dentaquest/Default/GCM Store/000003.log

View File

@@ -1 +0,0 @@
{"net":{"http_server_properties":{"servers":[{"anonymization":["FAAAABAAAABodHRwczovL2d2dDEuY29t",false,0],"server":"https://redirector.gvt1.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423536464638726","port":443,"protocol_str":"quic"}],"anonymization":["MAAAACsAAABodHRwczovL29wdGltaXphdGlvbmd1aWRlLXBhLmdvb2dsZWFwaXMuY29tAA==",false,0],"network_stats":{"srtt":19423},"server":"https://optimizationguide-pa.googleapis.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423536489859725","port":443,"protocol_str":"quic"}],"anonymization":["FAAAABAAAABodHRwczovL2d2dDEuY29t",false,0],"network_stats":{"srtt":14112},"server":"https://r12---sn-jvhj5nu-cvnl7.gvt1.com"},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423549147852405","port":443,"protocol_str":"quic"}],"anonymization":["HAAAABUAAABjaHJvbWU6Ly9uZXctdGFiLXBhZ2UAAAA=",true,0],"network_stats":{"srtt":21402},"server":"https://www.gstatic.com","supports_spdy":true},{"anonymization":["HAAAABYAAABodHRwczovL2RlbnRhcXVlc3QuY29tAAA=",false,0],"server":"https://dpm.demdex.net","supports_spdy":true},{"anonymization":["HAAAABYAAABodHRwczovL2RlbnRhcXVlc3QuY29tAAA=",true,0],"server":"https://greatdentalplans.demdex.net","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423549302118900","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABIAAABodHRwczovL2dvb2dsZS5jb20AAA==",false,0],"network_stats":{"srtt":35187},"server":"https://accounts.google.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423549302252025","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABIAAABodHRwczovL2dvb2dsZS5jb20AAA==",false,0],"network_stats":{"srtt":29518},"server":"https://www.google.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423549302459934","port":443,"protocol_str":"quic"}],"anonymization":["HAAAABUAAABjaHJvbWU6Ly9uZXctdGFiLXBhZ2UAAAA=",true,0],"network_stats":{"srtt":31079},"server":"https://ogads-pa.clients6.google.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423549302748269","port":443,"protocol_str":"quic"}],"anonymization":["HAAAABUAAABjaHJvbWU6Ly9uZXctdGFiLXBhZ2UAAAA=",true,0],"network_stats":{"srtt":28176},"server":"https://play.google.com","supports_spdy":true},{"anonymization":["HAAAABYAAABodHRwczovL2RlbnRhcXVlc3QuY29tAAA=",false,0],"server":"https://assets.adobedtm.com","supports_spdy":true},{"anonymization":["HAAAABYAAABodHRwczovL2RlbnRhcXVlc3QuY29tAAA=",false,0],"server":"https://dentaquest.sc.omtrdc.net","supports_spdy":true},{"anonymization":["HAAAABYAAABodHRwczovL2RlbnRhcXVlc3QuY29tAAA=",false,0],"server":"https://zn1zsy47ahixog4rc-cxinsight.siteintercept.qualtrics.com","supports_spdy":true},{"anonymization":["HAAAABYAAABodHRwczovL2RlbnRhcXVlc3QuY29tAAA=",false,0],"server":"https://providers-login.dentaquest.com","supports_spdy":true},{"anonymization":["HAAAABYAAABodHRwczovL2RlbnRhcXVlc3QuY29tAAA=",false,0],"server":"https://siteintercept.qualtrics.com","supports_spdy":true},{"anonymization":["HAAAABYAAABodHRwczovL2RlbnRhcXVlc3QuY29tAAA=",false,0],"server":"https://providers.dentaquest.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423549340838122","port":443,"protocol_str":"quic"}],"anonymization":["MAAAACwAAABodHRwczovL3Bhc3N3b3Jkc2xlYWtjaGVjay1wYS5nb29nbGVhcGlzLmNvbQ==",false,0],"network_stats":{"srtt":23504},"server":"https://passwordsleakcheck-pa.googleapis.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423549358008191","port":443,"protocol_str":"quic"}],"anonymization":["HAAAABYAAABodHRwczovL2RlbnRhcXVlc3QuY29tAAA=",false,0],"network_stats":{"srtt":34201},"server":"https://content-autofill.googleapis.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13423549384945647","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABIAAABodHRwczovL2dvb2dsZS5jb20AAA==",false,0],"network_stats":{"srtt":26030},"server":"https://android.clients.google.com","supports_spdy":true}],"supports_quic":{"address":"192.168.1.236","used_quic":true},"version":5},"network_qualities":{"CAESABiAgICA+P////8B":"4G"}}}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"preferred_apps":[],"version":1}

View File

@@ -1 +0,0 @@
{"protection":{"super_mac":"33F663353631B144EA660B5F809D89BA41CAF954EE5776BE5004BB589CA96BE1"}}

Some files were not shown because too many files have changed in this diff Show More