Left = original web-app plan · Right = proposed 5-week pilot (Aug 28 team decision) · Print landscape for review
What is the same in both plans? The investigation is provider-first (e.g. DHD). Claimants are not the target — they are conduits. Billing (~1M lines, ~4k providers) gives the claim list. Documents are added per claim for pattern work (boilerplate narratives, treatment intervals) plus fee checks and opinion letters.
What is different? Left: investigator pastes text in the web app (OCR outside our system). Right: files live on Google Drive; our script does OCR, builds JSON per claim, outputs a report — less database/UI work, faster pilot.
What we never do: Ask for documents for all 4,000 providers. Invent providers. Guess a wrong claim link and analyze as if it were correct.
In one sentence: PDFs are grouped by claim → investigator opens each claim in our app → pastes OCR text → we run analysis inside the product.
flowchart TB
classDef box fill:#ffffff,stroke:#000,stroke-width:2px
classDef soft fill:#f5f5f5,stroke:#000,stroke-width:2px
classDef out fill:#fff,stroke:#000,stroke-width:3px
classDef note fill:#eee,stroke:#666,stroke-width:1px
A["① Billing in DB"]:::box
B["② Pick provider DHD"]:::soft
C["③ Claims from billing"]:::soft
D["④ Docs per claim grouped"]:::box
E["⑤ Paste in web app"]:::soft
F["⑥ AI analysis"]:::soft
G["⑦ Findings in UI"]:::out
A --> B --> C --> D --> E --> F --> G
N["Doc→claim link known BEFORE paste"]:::note
N -.-> D
Who does what
| Step | Prep | Us (ManningKass) |
|---|---|---|
| Billing | CSV / bulk book ingested | Store lines, providers, claim case IDs |
| Pick target | Investigation target e.g. DHD | Filter billing to that Tax ID / provider |
| Documents | Files grouped by claim; OCR may run externally | Show claim list; accept paste per claim |
| Analysis | Review flags & export | Run patterns, fees, opinion letters in app |
Every step explained
~1 million billing lines, ~4,000 providers. Each row has: Tax ID, ClaimNumber, Claim Case (e.g. 1040386-01), service dates, CPT codes, amounts.
Note: Billing does not include patient names in a reliable way for matching files. Use claim case ID as the join key.
Example: DHD (already identified as suspect). Investigator selects provider from the book — not all 4k providers at once.
UI shows: list of claims + billing lines + fee flags already computed.
PDFs arrive already tied to a claim — folder, zip, or filename with claim case ID.
DHD/
1040386-01/
1040386-01 - CALVIN WRIGHT - MV104.pdf
1040386-01 - CALVIN WRIGHT - Initial.pdf
1045746-01/
...
Doc types needed for patterns: initial report, follow-up, MV-104/police, MRI/PT where billed — not only NF-3.
For each claim, for each document:
Demo mock: /ui/mock1 Flow A step 3.
One run per provider investigation: document patterns across claims + fee schedule + opinion letters matched to service type.
Output: flags table, narrative summary, CSV export, links to source text in app.
What we built toward this
In one sentence: Folder tree under providers/DHD/claimants/ → script reads PDFs/DOCs → structured text + JSON per claim → analyze all claims for that provider → report.
flowchart TB
classDef box fill:#ffffff,stroke:#000,stroke-width:2px
classDef soft fill:#f5f5f5,stroke:#000,stroke-width:2px
classDef out fill:#fff,stroke:#000,stroke-width:3px
classDef note fill:#eee,stroke:#666,stroke-width:1px
A["① Billing in DB"]:::box
B["② Pick provider DHD"]:::soft
C["③ Drive: providers/DHD/claimants"]:::box
D["④ Script: OCR+AI"]:::soft
E["⑤ JSON per claim"]:::soft
F["⑥ Analyze all JSONs"]:::soft
G["⑦ Report + Drive links"]:::out
A --> B --> C --> D --> E --> F --> G
U["unclassified_claimant_documents<br/>→ AI sort later"]:::note
U -.-> C
Part A — Folder structure must exist first
providers/ → one folder per provider (e.g. DHD/)providers/DHD/claimants/ → one folder per claim case ID from billing (e.g. 1040386-01/)providers/DHD/claimants/unclassified_claimant_documents/ → files not linked to a claim yet; AI sorting into claimant folders happens later (before analysis on those files)Part B — Our script runs on those folders
.json per claimPart C — Optional (not built in pilot UI)
v1: analysis runs on claimant folders with a known claim case ID. Unclassified folder = sorted by AI first, then included.
Google Drive layout (sample)
View live sample → Google Driveproviders/
└── DHD/ ← provider under investigation
└── claimants/
├── 1040386-01/ ← claim case ID (matches billing)
│ ├── MV104.pdf
│ ├── Initial_report.pdf
│ ├── MRI.doc
│ └── Follow_up.pdf
├── 1045746-01/
│ ├── Police_report.pdf
│ └── PT_notes.pdf
└── unclassified_claimant_documents/
├── scan_unknown_01.pdf ← claim not known yet
└── misc_document.doc → AI sorts into claimant folder later
Every step explained
We still use the ingested billing book. Investigator / script targets one provider (e.g. DHD). Claim case IDs from billing for that Tax ID are used as folder names.
PDFs and DOCs are placed under providers/DHD/claimants/{claim_case_id}/. Folder name must match billing claim case ID. Filenames can include patient name for readability.
Files with unknown claim → unclassified_claimant_documents/ until AI (or manual) sort moves them into the right claimant folder.
For each PDF, script produces our text format (not a copy of their form layout):
document_type: Initial report claim_case_id: 1040386-01 provider_name: DHD patient_name: CALVIN C. WRIGHT accident_date: 10/03/2018 chief_complaint: Neck and back pain after MVA... plan: PT, acupuncture, MRI if persistent... (full extracted body below)
Handwriting & messy scans = lower confidence; may need human check. Text saved on Drive (pay OCR cost once per file).
Script pulls billing lines for 1040386-01 from CSV/DB + attaches all doc texts from that folder:
1040386-01.json
{
"provider": "DHD",
"tax_id": "...",
"claim_case_id": "1040386-01",
"claim_number": "1040386",
"billing_lines": [ { "cpt": "99203", "amount": "...", ... } ],
"documents": [
{ "file": "MV104.pdf", "type": "MV-104", "text": "..." },
{ "file": "Initial_report.pdf", "type": "Initial report", "text": "..." }
]
}
Load all JSON files under providers/DHD/claimants/ (each claim case folder) — not one claim in isolation for cross-claim fraud patterns:
PDF/CSV + table of flags. Each finding links back to: claim case ID, JSON, original Drive PDF, billing line IDs.
Pilot UI: simple page — pick provider folder → run script → download report. No heavy DB ingest of every doc required.
Interactive walkthrough (sample data): /ui/mock2 (also /pilot-mock).
Live providers + report: /ui/mock4 (also /pilot-live).
unclassified_claimant_documents/ → sorts into the correct claimant folder → then same extract + JSON + analysis. Also supports starting from one big unsorted drop.
5-week rough plan (proposed)
| Week | Focus |
|---|---|
| 1 | providers/DHD/claimants/ sample on Drive; OCR script on 5–10 PDFs/DOCs |
| 2 | JSON builder + billing join by claim case ID; quality check text |
| 3 | Document pattern analysis across JSONs |
| 4 | Fee flags + opinion letter matching in report |
| 5 | End-to-end pilot on DHD batch + handoff doc |