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,154 @@
|
||||
"""
|
||||
Payer -> Group Name lookup.
|
||||
|
||||
python tests\\test_payer_groups.py
|
||||
|
||||
Exact-string match only, on purpose: eCW's own PAYER values already differ by
|
||||
case and spacing for what is really the same carrier (`United Healthcare` /
|
||||
`United Health Care` / `United healthcare` all appear in one real export), so
|
||||
"close enough" matching would have to guess which of several real, distinct
|
||||
strings a new one is closest to. Billing data does not get a guess — an
|
||||
unrecognized string must come back None and get a human's attention.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import pathlib
|
||||
import tempfile
|
||||
|
||||
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent.parent / "src"))
|
||||
|
||||
from ecw_bot.core import payer_groups # noqa: E402
|
||||
|
||||
TMP = pathlib.Path(tempfile.mkdtemp())
|
||||
|
||||
MAPPING = {
|
||||
"Medicaid": "Medicaid",
|
||||
"DentaQuest": "Dentaquest",
|
||||
"Anthem Blue Cross Blue Shield": "Commercial",
|
||||
}
|
||||
|
||||
|
||||
def case_exact_match_returns_group():
|
||||
assert payer_groups.classify("Medicaid", MAPPING) == "Medicaid"
|
||||
assert payer_groups.classify("DentaQuest", MAPPING) == "Dentaquest"
|
||||
|
||||
|
||||
def case_unmapped_payer_returns_none():
|
||||
assert payer_groups.classify("Some New Payer LLC", MAPPING) is None
|
||||
|
||||
|
||||
def case_case_sensitive_no_fuzzy_matching():
|
||||
"""Different case is a different string, on purpose — see module docstring."""
|
||||
assert payer_groups.classify("medicaid", MAPPING) is None
|
||||
assert payer_groups.classify("MEDICAID", MAPPING) is None
|
||||
|
||||
|
||||
def case_blank_or_none_payer_is_unmapped():
|
||||
assert payer_groups.classify("", MAPPING) is None
|
||||
assert payer_groups.classify(None, MAPPING) is None
|
||||
|
||||
|
||||
def case_load_mapping_reads_json_file():
|
||||
path = TMP / "mapping.json"
|
||||
path.write_text(json.dumps({"Medicaid": "Medicaid"}), encoding="utf-8")
|
||||
loaded = payer_groups.load_mapping(path)
|
||||
assert loaded == {"Medicaid": "Medicaid"}, loaded
|
||||
|
||||
|
||||
def case_load_mapping_missing_file_raises():
|
||||
try:
|
||||
payer_groups.load_mapping(TMP / "does_not_exist.json")
|
||||
except FileNotFoundError as exc:
|
||||
assert "does_not_exist.json" in str(exc), exc
|
||||
return
|
||||
raise AssertionError("expected FileNotFoundError")
|
||||
|
||||
|
||||
def case_seed_config_loads_and_covers_medicaid_and_dentaquest():
|
||||
"""
|
||||
The real config file this ships with, not a fixture. Since 2026-10-06 it
|
||||
is the team's Claim Status Dashboard pairs (tools/import_payer_groups.py),
|
||||
so its group names are the dashboard's own.
|
||||
"""
|
||||
mapping = payer_groups.load_mapping()
|
||||
assert mapping.get("Medicaid") == "Medicaid", mapping.get("Medicaid")
|
||||
assert mapping.get("DentaQuest") == "Dental - CHP+/DentaQuest", mapping.get("DentaQuest")
|
||||
assert mapping.get("Child Health Plan Plus") == "CHP+"
|
||||
|
||||
|
||||
RAE_PAYERS = [
|
||||
"BH COLORADO ACCESS",
|
||||
"BH ROCKY MOUNTAIN HEALTH",
|
||||
"BH ROCKY MTN HEALTH 2022",
|
||||
"BH ROCK MTN UB",
|
||||
"Carelon Behavioral Health, Inc",
|
||||
"CCH CO COMMUNITY HEALTH ALLIANCE",
|
||||
"HEALTH COLORADO INC",
|
||||
"Northeast Colorado Health Department",
|
||||
"Northeast Health Partners",
|
||||
]
|
||||
|
||||
|
||||
def case_seed_config_groups_the_nine_rae_payers_as_rae_payer():
|
||||
"""
|
||||
The client's own RAE list (document condition #11) — all Medicaid
|
||||
plans, grouped "RAE (Behavioral Health)" on the dashboard (the five the
|
||||
dashboard spells differently are kept by the import), and "RAE payer"
|
||||
for the conditions' rules. Plain "Medicaid" stays "Medicaid".
|
||||
"""
|
||||
mapping = payer_groups.load_mapping()
|
||||
for payer in RAE_PAYERS:
|
||||
assert payer_groups.classify(payer, mapping) == "RAE (Behavioral Health)", (payer, mapping.get(payer))
|
||||
assert payer_groups.rule_group(payer, mapping) == "RAE payer", payer
|
||||
assert payer_groups.classify("Medicaid", mapping) == "Medicaid"
|
||||
assert payer_groups.rule_group("Medicaid", mapping) == "Medicaid"
|
||||
|
||||
|
||||
DASH = {"Anthem": "Commercial Ins", "Rocky Mountain Health Prime":
|
||||
"Regional Accountable Entity-RAE (Reporting Group)",
|
||||
"Outreach": "Self Pay", "Kip": "Payer Not In Group",
|
||||
"CHP": "CHP+", "Old": "Commercial",
|
||||
"AARP Medicare Advantage": "Commercial Ins"}
|
||||
|
||||
|
||||
def case_rule_group_translates_dashboard_names_for_the_conditions():
|
||||
assert payer_groups.rule_group("Anthem", DASH) == "Commercial"
|
||||
assert payer_groups.rule_group("Rocky Mountain Health Prime", DASH) == "RAE payer"
|
||||
assert payer_groups.rule_group("Outreach", DASH) == "Program"
|
||||
assert payer_groups.rule_group("Kip", DASH) is None
|
||||
assert payer_groups.rule_group("CHP", DASH) == "CHP+" # passes through
|
||||
assert payer_groups.rule_group("Old", DASH) == "Commercial"
|
||||
assert payer_groups.rule_group("Unknown", DASH) is None
|
||||
|
||||
|
||||
def case_medicare_advantage_follows_the_dashboard():
|
||||
"""Operator ruling 2026-10-21: the dashboard's Commercial Ins, for every
|
||||
condition — no override keeps it on Medicare any more."""
|
||||
assert payer_groups.classify("AARP Medicare Advantage", DASH) == "Commercial Ins"
|
||||
assert payer_groups.rule_group("AARP Medicare Advantage", DASH) == "Commercial"
|
||||
assert payer_groups.RULE_OVERRIDES == {}
|
||||
|
||||
|
||||
CASES = [v for k, v in sorted(globals().items()) if k.startswith("case_")]
|
||||
|
||||
|
||||
def main() -> int:
|
||||
failures = 0
|
||||
for fn in CASES:
|
||||
name = fn.__name__[5:].replace("_", " ")
|
||||
try:
|
||||
fn()
|
||||
print(f" ok {name}")
|
||||
except AssertionError as exc:
|
||||
print(f" FAIL {name}: {exc}")
|
||||
failures += 1
|
||||
except Exception as exc:
|
||||
print(f" ERROR {name}: {type(exc).__name__}: {exc}")
|
||||
failures += 1
|
||||
print(f"\n{len(CASES) - failures}/{len(CASES)} passed")
|
||||
return 1 if failures else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user