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>
7.1 KiB
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>"andrun_allrecords that reason instead of applying it on ascreen == "dental"read — telehealth, medicare_telehealth, vaccine_admin_codes. - Dental claims are never saved in this change (operator), whatever
SAVE_CORRECTIONSsays; 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()returnsscreen("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 aretr[ng-repeat^="CPT in CPTCodes"](noCPTROW_id). - Per row: checkbox
[ng-click*="updateBillToIns("](same as UB/HCFA), code[data-fieldname="web_cptcode"], pointersweb_icd1..web_icd4, unitsweb_units, feeweb_billedFee(blur runseditCPTRow('BILLED_FEE')), DOSDentalClaimCPTSDOS. - 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 existingSEL_PROGRESS_NOTESmatches. - 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
- 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. - Reader (
pages/claim_form.py_EXTRACT_JS): read Dental rows into the samecptrow shape (code,icd1..4,units,billed_fee,billed,sdos;pos/mod1..4empty), insurance from#DentalClaimTbl2, the Dental claim number, ICD list, andnotesfrom#dentalClaimNotes. Oneextract()for all three screens. - 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 (whenOPEN_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. - 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. - 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.
- Saving: Dental claims are never saved in this change, whatever
SAVE_CORRECTIONSsays. 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.htmlfrom 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 expectedcptandinsurance.- 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.