Initial import: eCW Charge Validation bot and results Portal
Snapshot of the working project as of 2026-10-23 (local 2d4d4fc), one commit with no earlier history: the tracked files were de-identified first (synthetic claim ids and patient data only; see Context.md section 7). Credentials, run logs, screenshots, claim reports and client workbooks are gitignored and not included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
ba15a574ab
205 files changed
+56772
No files matched your search
@@ -0,0 +1,137 @@
|
||||
# Dental claims run every applicable condition — design
|
||||
|
||||
Date: 2026-10-07. Status: approved in chat (operator, 2026-10-07);
|
||||
implemented 2026-10-12 (operator: "this is our number one condition").
|
||||
|
||||
## 2026-10-12 update (as built)
|
||||
|
||||
- The rule now also covers #12 (H codes: BH payer → modifier removed;
|
||||
any other payer → line unchecked + fee 0) and #14 (Medicare: G8510 /
|
||||
G8431 unchecked + fee 0, #6 not run). Both run on Dental claims like
|
||||
every other condition; #12's BH path has no modifier column to read on
|
||||
the Dental grid, so it never fires there.
|
||||
- A fix the Dental screen cannot hold → **Review** (operator): a condition
|
||||
module declares `DENTAL_UNSUPPORTED = "<reason>"` and `run_all` records
|
||||
that reason instead of applying it on a `screen == "dental"` read —
|
||||
telehealth, medicare_telehealth, vaccine_admin_codes.
|
||||
- Dental claims are **never saved** in this change (operator), whatever
|
||||
`SAVE_CORRECTIONS` says; the review-before-close box still shows.
|
||||
- A Dental claim is read and run through the conditions even with
|
||||
CHECK_HIGH_RISK and CHECK_SLIDING_FEE both off (it used to come back
|
||||
blank).
|
||||
- The Charge Summary applies the same claim-level checks (note read, CPT /
|
||||
ICD rows read, conditions run) to a Dental read as to UB/HCFA.
|
||||
- Row selectors gained a third (Dental) alternative, scoped to the Dental
|
||||
window on screen (`:visible`); `extract()` returns `screen`
|
||||
("ub" / "hcfa" / "dental").
|
||||
- Not live-verified yet: the first live run should be SAVE-off on a few
|
||||
Dental claims (one with DCONS or Dscprit).
|
||||
|
||||
## Rule (operator, 2026-10-07)
|
||||
|
||||
Every claim is checked against **every condition whose Payer column is
|
||||
"All" / "All payers"**, **plus** every condition specific to that claim's
|
||||
payer (Medicare, Medicaid, Dental payers, ...). This holds for every payer
|
||||
and every claim screen — UB, HCFA and Dental alike.
|
||||
|
||||
UB and HCFA claims already work this way: each claim runs the whole
|
||||
registry (`conditions/__init__.py` `CONDITIONS`) and each condition's own
|
||||
`detect()` decides from the claim's codes and payer. **The gap is Dental:** a
|
||||
Dental claim today runs only #15 high risk and #8 sliding fee and never
|
||||
reaches `run_all`. So, for example, `dummy_codes` (DCONS/Dscprit, which are
|
||||
Dental codes) can never fire on any claim.
|
||||
|
||||
## What a Dental claim will run
|
||||
|
||||
| Doc # | Condition | Payer (document) | Module |
|
||||
|---|---|---|---|
|
||||
| 5 | J2930/J2001 uncheck + fee 0 | ALL | `j2930_j2001_update` |
|
||||
| 6 | Depression DX pointer | All | `depression_dx_pointer` |
|
||||
| 7 | Zero-fee uncheck / priced line check | ALL | `zero_fee_uncheck`, `priced_line_check` |
|
||||
| 21 | Telehealth POS 2 + modifier | All | `telehealth` |
|
||||
| 22 | Medicare telehealth G2025 | Medicare | `medicare_telehealth` |
|
||||
| 18 | Vaccine admin codes | All except Medicare | `vaccine_admin_codes` |
|
||||
| 8 | DCONS/Dscprit uncheck + fee 0 | All Dental Payer | `dummy_codes` |
|
||||
| 8 | Sliding fee date check | All Dental Payer | `pages/sliding_fee` (unchanged) |
|
||||
| 15 | High risk in Billing Notes | Dental Payers | `pages/dental_notes` (unchanged) |
|
||||
|
||||
No condition gains a form-type check: each still decides from codes and
|
||||
payer only. A condition whose codes are not on the claim does nothing.
|
||||
|
||||
## Dental screen facts (from Dom.txt, claim screen `.modal[id^="dentalClaim"]`)
|
||||
|
||||
- CPT/CDT grid `table[id^="claimCPTCodesTable"]`; real rows are
|
||||
`tr[ng-repeat^="CPT in CPTCodes"]` (no `CPTROW_` id).
|
||||
- Per row: checkbox `[ng-click*="updateBillToIns("]` (same as UB/HCFA), code
|
||||
`[data-fieldname="web_cptcode"]`, pointers `web_icd1`..`web_icd4`, units
|
||||
`web_units`, fee `web_billedFee` (blur runs `editCPTRow('BILLED_FEE')`),
|
||||
DOS `DentalClaimCPTSDOS`.
|
||||
- **No per-row POS and no modifier columns.** POS is claim-level
|
||||
(`ng-model="ClaimData.pos"`).
|
||||
- Prog. Notes button `button[ng-click="viewProgNote()"]`
|
||||
(`dentalClaimProgressNoteBtn…`) — the existing `SEL_PROGRESS_NOTES` matches.
|
||||
- Insurance grid: `#DentalClaimTbl2` (Bill To, Ins Id, Name, ...).
|
||||
- Billing Notes: `#dentalClaimNotes` (already read by high risk).
|
||||
|
||||
None of the row fields has been exercised live yet; Dom.txt is one capture.
|
||||
|
||||
## Design
|
||||
|
||||
1. **Selectors** (`selectors/claim_form.py`): add the Dental alternative to
|
||||
each row selector the helpers already use — `SEL_CPT_ROWS`,
|
||||
`SEL_CPT_CODE`, `SEL_CPT_ICD1..4`, `SEL_CPT_BILLED_FEE`, `SEL_CPT_UNITS`.
|
||||
The Dental row selector is scoped under `.modal[id^="dentalClaim"]` so it
|
||||
cannot match a grid on another screen. Within one row only one alternative
|
||||
ever matches, the same contract the UB/HCFA pairs rely on.
|
||||
2. **Reader** (`pages/claim_form.py` `_EXTRACT_JS`): read Dental rows into the
|
||||
same `cpt` row shape (`code`, `icd1..4`, `units`, `billed_fee`, `billed`,
|
||||
`sdos`; `pos`/`mod1..4` empty), insurance from `#DentalClaimTbl2`, the
|
||||
Dental claim number, ICD list, and `notes` from `#dentalClaimNotes`.
|
||||
One `extract()` for all three screens.
|
||||
3. **Flow** (`flows/export_medcor_ready.py`): a Dental claim runs high risk +
|
||||
sliding fee first (unchanged, read-only), then the same path as UB/HCFA:
|
||||
`extract()`, Prog. Notes (when `OPEN_PROGRESS_NOTES`), `run_all`, per-claim
|
||||
box, Charge Summary. The Dental results stay on the claim's data so the box
|
||||
and the summary show both.
|
||||
4. **A fix the Dental screen cannot make** — e.g. telehealth needs a row
|
||||
modifier and the Dental grid has none, or POS is claim-level: the condition
|
||||
returns `declined(...)` with the reason ("Dental screen has no modifier
|
||||
column"), so the claim is **Review** in the Charge Summary. Never a silent
|
||||
skip, never a guess.
|
||||
5. **Charge Summary**: one row per claim combining condition comments with the
|
||||
Dental findings (HIGH RISK, sliding fee). Category: Review beats Fail beats
|
||||
Pass, as today.
|
||||
6. **Saving**: Dental claims are **never saved** in this change, whatever
|
||||
`SAVE_CORRECTIONS` says. Their corrections are shown and listed as
|
||||
"Corrections pending (not saved)". Dental save is enabled only after a live
|
||||
verification-mode run confirms the row writes.
|
||||
|
||||
## Error handling
|
||||
|
||||
- Dental form not loaded (`wait_claim_loaded`): conditions skipped, claim is
|
||||
Review — same as HCFA today.
|
||||
- A Dental row field missing (fee or checkbox not found): the existing helpers
|
||||
already treat a missing field as unknown, not as zero/unchecked.
|
||||
- High risk / sliding fee failures keep their current Review handling.
|
||||
|
||||
## Testing
|
||||
|
||||
- Grow `tests/fixtures/dental_claim.html` from Dom.txt's real Dental grid
|
||||
(rows, checkbox, fee, pointers, insurance grid, Prog. Notes button) with no
|
||||
patient data.
|
||||
- `extract()` on the Dental fixture returns the expected `cpt` and `insurance`.
|
||||
- Per condition, a Dental case: dummy codes (DCONS/Dscprit) uncheck + zero;
|
||||
J2001 uncheck + zero; zero-fee uncheck; priced line check; depression
|
||||
pointer retag on `web_icd*`; telehealth on Dental → declined/Review.
|
||||
- Flow: a Dental claim gets high risk + sliding fee **and** condition results
|
||||
in one summary row; never offered Save.
|
||||
- Full suite stays green.
|
||||
- Live: one SAVE-off run on Dental test claims (with a DCONS or Dscprit line)
|
||||
before Dental save is considered.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- New document conditions not yet built (#3, #4, #9-#14, #16, #19, #20,
|
||||
#23-#55).
|
||||
- Saving Dental claims.
|
||||
- "Special programs" half of #8.
|
||||
Reference in new issue
Block a user