feat(backend): structural + CO Medicaid validation rules

This commit is contained in:
Tyler
2026-06-19 15:45:17 -06:00
parent 9db793c108
commit 1cab95ffc3
2 changed files with 267 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
from datetime import date
from decimal import Decimal
import pytest
from cyclone.parsers.models import (
Address,
BillingProvider,
ClaimHeader,
ClaimOutput,
Diagnosis,
Envelope,
Payer,
Procedure,
ServiceLine,
Subscriber,
ValidationReport,
)
from cyclone.parsers.payer import PayerConfig
from cyclone.parsers.validator import validate
def _build_claim(**overrides) -> ClaimOutput:
"""Build a passing claim for tests; override fields to break specific rules."""
base = dict(
claim_id="C1",
control_number="991102977",
transaction_date=date(2026, 6, 11),
billing_provider=BillingProvider(
name="Test Provider",
npi="1234567890",
tax_id="123456789",
address=Address(line1="1 Main", city="X", state="CO", zip="80000"),
),
subscriber=Subscriber(
first_name="John",
last_name="Doe",
member_id="M1",
dob=date(1980, 1, 1),
gender="M",
address=Address(line1="1 Main", city="X", state="CO", zip="80000"),
),
payer=Payer(name="COHCPF", id="SKCO0"),
claim=ClaimHeader(
claim_id="C1",
total_charge=Decimal("100.00"),
place_of_service="12",
frequency_code="1",
provider_signature="Y",
assignment="Y",
release_of_info="Y",
),
diagnoses=[Diagnosis(code="Z00", qualifier="ABK")],
service_lines=[
ServiceLine(
line_number=1,
procedure=Procedure(qualifier="HC", code="99213", modifiers=[]),
charge=Decimal("100.00"),
unit_type="UN",
units=Decimal("1.0"),
service_date=date(2026, 6, 11),
)
],
validation=ValidationReport(passed=True, errors=[], warnings=[]),
raw_segments=[],
)
base.update(overrides)
return ClaimOutput(**base)
def test_validate_passing_claim():
cfg = PayerConfig.co_medicaid()
report = validate(_build_claim(), cfg)
assert report.passed is True
assert report.errors == []
def test_r010_clm01_required():
cfg = PayerConfig.co_medicaid()
claim = _build_claim()
claim.claim.claim_id = ""
report = validate(claim, cfg)
assert not report.passed
assert any(i.rule == "R010_clm01_present" for i in report.errors)
def test_r011_total_charge_positive():
cfg = PayerConfig.co_medicaid()
claim = _build_claim()
claim.claim.total_charge = Decimal("0.00")
report = validate(claim, cfg)
assert any(i.rule == "R011_total_charge_positive" for i in report.errors)
def test_r020_npi_must_be_ten_digits():
cfg = PayerConfig.co_medicaid()
claim = _build_claim()
claim.billing_provider.npi = "12345"
report = validate(claim, cfg)
assert any(i.rule == "R020_npi_format" for i in report.errors)
def test_r030_frequency_allowed():
cfg = PayerConfig.co_medicaid() # only 1, 7, 8
claim = _build_claim()
claim.claim.frequency_code = "5"
report = validate(claim, cfg)
assert any(i.rule == "R030_frequency_allowed" for i in report.errors)
def test_r031_ref_g1_optional_no_error():
"""R031 is informational in v1 — no REF*G1 should not error."""
cfg = PayerConfig.co_medicaid()
claim = _build_claim()
report = validate(claim, cfg)
assert not any(i.rule == "R031_ref_g1_optional" and i.severity == "error" for i in report.errors)
def test_r050_diagnosis_required():
cfg = PayerConfig.co_medicaid()
claim = _build_claim(diagnoses=[])
report = validate(claim, cfg)
assert any(i.rule == "R050_diagnosis_present" for i in report.errors)
def test_r060_service_dates_required():
cfg = PayerConfig.co_medicaid()
claim = _build_claim()
claim.service_lines[0].service_date = None
report = validate(claim, cfg)
assert any(i.rule == "R060_service_dates_present" for i in report.errors)
# Now add the date:
claim.service_lines[0].service_date = date(2026, 6, 11)
report = validate(claim, cfg)
assert not any(i.rule == "R060_service_dates_present" for i in report.errors + report.warnings)
def test_r070_charges_sum_warning():
cfg = PayerConfig.co_medicaid()
claim = _build_claim()
claim.claim.total_charge = Decimal("999.00") # mismatch
report = validate(claim, cfg)
assert any(i.rule == "R070_charges_sum" and i.severity == "warning" for i in report.warnings)
def test_r100_payer_id_warning_only():
cfg = PayerConfig.co_medicaid()
claim = _build_claim()
claim.payer.id = "WRONG"
report = validate(claim, cfg)
assert any(i.rule == "R100_payer_id_matches" and i.severity == "warning" for i in report.warnings)
assert report.passed is True