""" ClaimReady — pre-submission claim checker (Gradio UI). Pre-checks hospital insurance claim / pre-auth document sets against the Standard Treatment Guidelines before they're uploaded to the government portal. OCR + content verification run inside the Space on Gemma 3 12B via transformers (GPU), with no cloud inference API. """ import gradio as gr from llm import LLMConfigError, verify, _file_to_images from packages import ( STAGE_PREAUTH, STAGE_CLAIM, STAGE_LABELS, dropdown_choices, get_package, required_documents, ) STAGE_RADIO_CHOICES = [ (STAGE_LABELS[STAGE_PREAUTH], STAGE_PREAUTH), (STAGE_LABELS[STAGE_CLAIM], STAGE_CLAIM), ] # Synthetic (fictional-patient) sample claims — safe to publish, let judges try # the app in one click. NO real patient data. # (label, package_code, stage, files) — synthetic, fictional-patient sample claims. SAMPLES = [ ("🤒 Enteric Fever · Pre-Auth · EN+हिन्दी", "MG006A", STAGE_PREAUTH, ["samples/enteric_clinical_notes.png", "samples/enteric_cbc.png"]), ("🤒 Enteric Fever · Claim · EN+हिन्दी", "MG006A", STAGE_CLAIM, ["samples/enteric_indoor_case.png", "samples/enteric_post_cbc.png", "samples/enteric_discharge.png"]), ("🩸 Severe Anemia · Pre-Auth · EN+తెలుగు", "MG064A", STAGE_PREAUTH, ["samples/anemia_clinical_notes.png", "samples/anemia_cbc_hb.png"]), ("🩸 Severe Anemia · Claim · EN+తెలుగు", "MG064A", STAGE_CLAIM, ["samples/anemia_indoor_case.png", "samples/anemia_post_cbc.png", "samples/anemia_discharge.png"]), ] def package_info_md(code): pkg = get_package(code) if not pkg: return "" return ( f"**{pkg['code']} — {pkg['name']}** \n" f"Procedure: {pkg.get('procedure', '—')} \n" f"Specialty: {pkg.get('specialty', '—')} \n" f"Package price: {pkg.get('price', '—')}" ) def checklist_md(code, stage): if not code or not stage: return "_Select a package and stage to see the required documents._" pkg = get_package(code) docs = required_documents(code, stage) if not docs: return "_No documents configured for this selection._" lines = [ f"### Required documents — {STAGE_LABELS[stage]}", f"_{pkg['name']} ({pkg['code']})_", "", ] for i, doc in enumerate(docs, 1): line = f"{i}. **{doc['label']}** — {doc['verify']}" if doc.get("note"): line += f" \n _Note: {doc['note']}_" lines.append(line) rules = pkg.get("rules", []) if rules: lines.append("") lines.append("**Compliance checks (content):**") for r in rules: lines.append(f"- {r['check']}") return "\n".join(lines) def on_package_change(code, stage): return package_info_md(code), checklist_md(code, stage) def on_stage_change(code, stage): return checklist_md(code, stage) def show_documents(files): """Render the uploaded/sample files (PDF pages too) into gallery images.""" images = [] for f in files or []: path = getattr(f, "name", f) try: images.extend(_file_to_images(path)) except Exception: pass return images def run_verification(code, stage, files): if not code: yield "⚠️ Please select a package code first." return if not stage: yield "⚠️ Please select a stage (Pre-Auth or Claim)." return if not files: yield "⚠️ Please upload at least one document to verify." return pkg = get_package(code) docs = required_documents(code, stage) paths = [getattr(f, "name", f) for f in files] yield ( f"⏳ **Analyzing {len(paths)} document(s)…** " "Reading each page and checking it against the guidelines — " "the assistive review will appear here shortly." ) try: result = verify(pkg, STAGE_LABELS[stage], docs, pkg.get("rules", []), paths) except LLMConfigError as e: yield f"## ⚠️ Configuration error\n\n{e}" return except Exception as e: yield ( "## ❌ Verification failed\n\n" f"The model did not complete: `{type(e).__name__}: {e}`" ) return yield result # --- Styling ------------------------------------------------------------------ THEME = gr.themes.Soft( primary_hue=gr.themes.colors.teal, secondary_hue=gr.themes.colors.blue, neutral_hue=gr.themes.colors.slate, font=[gr.themes.GoogleFont("Inter"), "system-ui", "sans-serif"], ).set( body_background_fill="#eef2f6", block_background_fill="#ffffff", block_border_width="1px", block_shadow="0 1px 3px rgba(16,24,40,.06)", block_radius="14px", ) CSS = """ .gradio-container {max-width: 1500px !important; width: 96% !important; margin: auto !important;} #hero { background: linear-gradient(135deg, #2563eb 0%, #06b6d4 100%); color: #fff; border-radius: 16px; padding: 28px 32px; margin-bottom: 6px; box-shadow: 0 10px 26px rgba(37,99,235,.28); } #hero h1 {margin: 0 0 8px 0; font-size: 31px; font-weight: 800; text-shadow: 0 1px 2px rgba(0,0,0,.18);} #hero p {margin: 0; color:#f0f9ff; opacity: 1; font-size: 15.5px; line-height: 1.55;} #hero p b {color:#ffffff;} #hero .pills {margin-top: 16px;} #hero .pill { display:inline-block; background: rgba(255,255,255,.22); border:1px solid rgba(255,255,255,.45); color:#fff; padding: 5px 13px; border-radius: 999px; font-size: 12.5px; margin: 0 8px 6px 0; font-weight: 500; } #run-btn {font-weight: 700; font-size: 16px;} #result-card .prose {font-size: 15px;} .step-label {font-weight: 700; color:#0f4c81; margin-bottom: 2px;} footer {display: none !important;} #foot {text-align:center; color:#64748b; font-size:12.5px; margin-top:10px;} /* keep text + list markers off the edge so the first glyph never clips */ .prose, .md, .prose *, .md * {overflow: visible !important;} .prose {padding: 2px 6px !important;} .prose ul, .prose ol {padding-left: 1.6em !important; margin-left: 0 !important;} .prose li {line-height: 1.6; margin: 4px 0;} .prose p, .prose h1, .prose h2, .prose h3, .prose h4 {line-height: 1.55;} #problem-sidebar {padding: 6px 18px 16px 22px !important;} #result-card {padding: 2px 18px !important;} """ HERO = """
An assistive pre-check for hospital insurance claim and pre-authorization document sets. Before you upload to the government portal, ClaimReady reads each document and checks it against the Standard Treatment Guidelines, highlighting missing papers and possible compliance gaps so your team can fix them early and reduce rejections.