Spaces:
Sleeping
Plum OPD Claim Adjudication Tool
An intelligent, multimodal claim adjudication system for OPD (Outpatient Department) insurance claims. It combines a deterministic policy rules engine with Google Gemini 2.5 Flash to automate document extraction, eligibility checks, and final claim decisions β surfacing only genuinely ambiguous cases to human reviewers.
Table of Contents
System Architecture
The system is composed of three tiers: a Streamlit web portal for claimants, a FastAPI backend hosting the adjudication logic, and two external services β the Gemini 2.5 Flash API for multimodal AI and a relational database for persistence.
graph TD
User(["User / Claimant"]) <-->|"Browser / UI"| Streamlit["Streamlit Portal"]
Streamlit <-->|"HTTP / JSON"| FastAPI["FastAPI Backend Application"]
subgraph Backend ["FastAPI Backend"]
Router["API Router"] <--> Repository["Repository CRUD Layer"]
Router <--> PolicyService["Policy & Rules Engine"]
Router <--> GeminiService["Gemini Integration Services"]
PolicyService -->|"Check Rules"| ConfCalc["Confidence & Flags Calculator"]
end
GeminiService <-->|"Multimodal API / SDK"| GeminiAPI["Google Gemini 2.5 Flash API"]
Repository <-->|"SQLAlchemy ORM"| DB[("SQLite / PostgreSQL Database")]
classDef main fill:#1E3A8A,color:#fff,stroke:#10B981,stroke-width:2px;
classDef external fill:#111827,color:#fff,stroke:#F59E0B,stroke-width:2px;
classDef secondary fill:#F3F4F6,color:#1E293B,stroke:#9CA3AF,stroke-width:1px;
class Streamlit,FastAPI,PolicyService,GeminiService main;
class GeminiAPI,DB external;
class Router,Repository,ConfCalc secondary;
Component Summary
| Component | Role |
|---|---|
| Streamlit Portal | Browser-based UI for claim submission and status tracking |
| FastAPI Backend | REST API gateway; orchestrates all backend services |
| API Router | Routes incoming requests to the appropriate service layer |
| Repository (CRUD) | SQLAlchemy-based data access layer for all DB operations |
| Policy & Rules Engine | Deterministic eligibility checks (waiting period, annual limit, member status) |
| Confidence & Flags Calculator | Computes composite confidence score; raises fraud/ambiguity flags |
| Gemini Integration Services | Handles OCR extraction and AI-based adjudication via Gemini SDK |
| Gemini 2.5 Flash API | Google's multimodal LLM β processes bills, prescriptions, lab reports |
| Database | Stores members, claims, documents, results, and audit logs |
Database Schema (ER Diagram)
Five entities capture the full lifecycle of a claim β from member identity through document ingestion, adjudication result, and audit trail.
erDiagram
MEMBERS {
string id PK "e.g., EMP001"
string name
string policy_number
date join_date
float annual_limit_remaining
string status "ACTIVE / INACTIVE"
}
CLAIMS {
string id PK "e.g., CLM_XXXXX"
string member_id FK
string patient_name
float claim_amount
string status "PENDING / APPROVED / REJECTED / PARTIAL / MANUAL_REVIEW"
string hospital_name
boolean cashless_request
date treatment_date
timestamp submitted_at
timestamp updated_at
}
CLAIM_DOCUMENTS {
int id PK
string claim_id FK
string document_type "PRESCRIPTION / BILL / LAB_REPORT / OTHER"
string file_path
string file_name
int file_size
json extracted_data
text raw_llm_response
}
ADJUDICATION_RESULTS {
int id PK
string claim_id FK "Unique"
string decision "APPROVED / REJECTED / PARTIAL / MANUAL_REVIEW"
float approved_amount
float confidence_score
json reasons "List of strings"
json flags "List of strings"
text notes
text next_steps
json policy_engine_log
timestamp created_at
}
AUDIT_LOGS {
int id PK
string claim_id FK
string action "e.g., CLAIM_SUBMITTED, OCR_EXTRACTED"
timestamp timestamp
text details
}
MEMBERS ||--o{ CLAIMS : "submits"
CLAIMS ||--o{ CLAIM_DOCUMENTS : "contains"
CLAIMS ||--|| ADJUDICATION_RESULTS : "produces"
CLAIMS ||--o{ AUDIT_LOGS : "records"
Relationships
| Relationship | Cardinality | Description |
|---|---|---|
MEMBERS β CLAIMS |
One-to-many | A member can submit multiple claims |
CLAIMS β CLAIM_DOCUMENTS |
One-to-many | A claim can have multiple supporting documents |
CLAIMS β ADJUDICATION_RESULTS |
One-to-one | Each claim produces exactly one adjudication result |
CLAIMS β AUDIT_LOGS |
One-to-many | Every state change on a claim is logged |
Claim Decision Flow
The adjudication engine processes each submitted claim through three sequential stages: deterministic eligibility checks, AI-powered medical necessity review, and a confidence threshold gate before final status assignment.
graph TD
Start(["Claim Submitted"]) --> Upload["Save Documents & Metadata"]
Upload --> OCR["Gemini Multimodal OCR & Extraction"]
OCR --> DeterministicChecks{"Run Deterministic Checks"}
DeterministicChecks -->|"Failed: Member Inactive / Waiting Period / Per-claim Exceeded"| Reject["Set Status: REJECTED"]
DeterministicChecks -->|"Passed: Basic Eligibility Met"| AICheck{"Run Gemini AI Adjudication"}
AICheck -->|"Exclusions Found / Lack of Medical Necessity"| AIReject["Set Status: REJECTED or PARTIAL"]
AICheck -->|"Valid & Medically Necessary"| CalcLimits["Calculate Limits & Copays / Discounts"]
CalcLimits --> ConfidenceCheck{"Evaluate Composite Confidence"}
ConfidenceCheck -->|"Confidence < 70% or Fraud Flags"| Review["Set Status: MANUAL_REVIEW"]
ConfidenceCheck -->|"Confidence >= 70% & No Flags"| Approve["Set Status: APPROVED or PARTIAL"]
Approve --> UpdateLimit["Deduct Approved Amount from YTD Limit"]
UpdateLimit --> Log["Record Adjudication & Update Status"]
Reject --> Log
AIReject --> Log
Review --> Log
Log --> End(["Processing Complete"])
classDef process fill:#DBEAFE,color:#1E40AF,stroke:#3B82F6;
classDef decision fill:#FEF3C7,color:#92400E,stroke:#F59E0B;
classDef terminal fill:#FEE2E2,color:#991B1B,stroke:#EF4444;
classDef start fill:#D1FAE5,color:#065F46,stroke:#10B981;
class Start,End start;
class DeterministicChecks,AICheck,ConfidenceCheck decision;
class Upload,OCR,CalcLimits,UpdateLimit,Log process;
class Reject,AIReject,Review,Approve terminal;
Decision Stages
Stage 1 β Deterministic Checks Hard policy rules evaluated before any AI call. A failure here results in an immediate rejection.
| Check | Fail Condition |
|---|---|
| Member status | Member is INACTIVE |
| Waiting period | Treatment date is within the policy's waiting window |
| Per-claim limit | Claimed amount exceeds the maximum allowable per single claim |
Stage 2 β Gemini AI Adjudication Gemini 2.5 Flash reviews the extracted document data against policy exclusions and assesses medical necessity.
| Outcome | Description |
|---|---|
REJECTED |
Claim falls under a policy exclusion |
PARTIAL |
Partial medical necessity β only a portion of the claim is valid |
| Passes | Claim is valid and medically necessary β proceeds to limit calculation |
Stage 3 β Confidence Gate A composite confidence score is computed from OCR quality, AI certainty, and policy match strength.
| Score | Fraud Flags | Final Status |
|---|---|---|
| β₯ 70% | None | APPROVED or PARTIAL |
| < 70% | Any | MANUAL_REVIEW |
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | Streamlit |
| Backend API | FastAPI (Python) |
| ORM | SQLAlchemy |
| Database | SQLite (dev) / PostgreSQL (prod) |
| AI / OCR | Google Gemini 2.5 Flash (multimodal) |
| Document types | Prescriptions, hospital bills, lab reports |