Files
stack/tests/pfs/test_descriptors.py
kert c8ba1bbefa fix(pfs): C1 — descriptor-stem regex and element-paragraph heuristic swallow FR cross-reference lines
`_stem_pattern`'s `re.I` made `[A-Z]` match any letter, so an enumeration
item like "( 9) 99439 (code for non-complex chronic care management)."
read as the opening of 99439's own descriptor; `descriptor_runs` then
consumed the following list item as an element paragraph, and
`extract_run` minted rows anchored to a paragraph naming a different
code entirely. Live table already held wrong rows from this (an APCM
paragraph under 99439, a TCM enumeration line under 99490).

Keep the stem match case-insensitive (some rules print descriptors
lowercase) but reject the cross-reference form with a negative lookahead
on "code(s)". `is_element_paragraph` also rejects lines that open with
an enumeration marker or contain "code(s) for" — the same enumeration
items were passing its ")."-ending heuristic too.

Claude-Session: https://claude.ai/code/session_01Aum3pEMAM3yQVdFSdVe6Gc
2026-09-09 14:10:14 -04:00

230 lines
7.6 KiB
Python

"""pfs.descriptors — where descriptor text comes from."""
from __future__ import annotations
import sqlite3
import duckdb
import pytest
from pfs.descriptors import (
DescriptorRun,
descriptor_runs,
hcpcs_long_description,
rule_year_of,
rvu_descriptions,
)
class _Store:
"""Minimal stand-in for bib.Store: only ``_con()`` is used."""
def __init__(self) -> None:
self.con = sqlite3.connect(":memory:")
self.con.row_factory = sqlite3.Row
self.con.executescript(
"""
CREATE TABLE items (key TEXT PRIMARY KEY, title TEXT, date_published TEXT);
CREATE TABLE fr_anchors (item_key TEXT, p_id INTEGER, page INTEGER, ordinal INTEGER, text TEXT);
"""
)
def _con(self):
return self.con
def close(self):
self.con.close()
@pytest.fixture
def store():
s = _Store()
s.con.execute(
"INSERT INTO items VALUES ('DE2VH9PD', 'Medicare Program; CY 2015 PFS Final Rule', '2014-11-13')"
)
rows = [
(
"DE2VH9PD",
1243,
67716,
"Comment: commenters noted the CPT panel created a code.",
),
(
"DE2VH9PD",
1244,
67716,
"These commenters suggested that we use the new CPT code 99490 (Chronic care management services, at least 20 minutes of clinical staff time directed by a physician or other qualified health care professional, per calendar month, with the following required elements:",
),
(
"DE2VH9PD",
1245,
67716,
"Multiple (two or more) chronic conditions expected to last at least 12 months, or until the death of the patient;",
),
(
"DE2VH9PD",
1246,
67716,
"Chronic conditions place the patient at significant risk of death, acute exacerbation/decompensation, or functional decline;",
),
(
"DE2VH9PD",
1247,
67716,
"Comprehensive care plan established, implemented, revised, or monitored).",
),
(
"DE2VH9PD",
1248,
67716,
"Many of these commenters expressed a preference for the per calendar month period.",
),
("DE2VH9PD", 1249, 67716, "Response: It is our preference to use CPT codes."),
]
s.con.executemany(
"INSERT INTO fr_anchors VALUES (?,?,?,?,?)",
[(k, p, pg, p, t) for k, p, pg, t in rows],
)
yield s
s.close()
@pytest.fixture
def con():
c = duckdb.connect(":memory:")
c.execute("CREATE SCHEMA terminology; CREATE SCHEMA pfs")
c.execute(
"CREATE TABLE terminology.hcpcs_level_2 (hcpcs VARCHAR, seqnum VARCHAR, recid VARCHAR, long_description VARCHAR, short_description VARCHAR)"
)
c.execute(
"INSERT INTO terminology.hcpcs_level_2 VALUES ('G0556','10','3','Advanced primary care management services … per calendar month','Adv prim care mgmt lvl 1')"
)
c.execute(
"INSERT INTO terminology.hcpcs_level_2 VALUES ('G0556','5','1','Lower seqnum description for G0556','Short desc')"
)
c.execute(
"CREATE TABLE pfs.rvu (hcpcs VARCHAR, mod VARCHAR, description VARCHAR, status_code VARCHAR, year INTEGER)"
)
c.executemany(
"INSERT INTO pfs.rvu VALUES (?,?,?,?,?)",
[
("99490", None, "Chron care mgmt srvc 20 min", "A", 2015),
("99490", "26", "ignored modifier row", "A", 2015),
("99490", "", "Chrnc care mgmt staff 1st 20", "A", 2022),
],
)
yield c
c.close()
class TestRuleYear:
def test_from_title(self):
assert (
rule_year_of("Medicare Program; CY 2015 PFS Final Rule", "2014-11-13")
== 2015
)
assert (
rule_year_of(
"Medicare and Medicaid Programs; CY 2027 Payment Policies", "2026-07-16"
)
== 2027
)
def test_fallback_to_date_plus_one(self):
assert rule_year_of("Revisions to Payment Policies", "2017-07-21") == 2018
class TestDescriptorRuns:
def test_stem_and_following_elements(self, store):
runs = descriptor_runs(store, "99490")
assert len(runs) == 1
run = runs[0]
assert isinstance(run, DescriptorRun)
assert run.item_key == "DE2VH9PD" and run.rule_year == 2015
assert run.stem.p_id == 1244
assert [p.p_id for p in run.elements] == [1245, 1246, 1247]
assert (
"per calendar month" in run.text and "Comprehensive care plan" in run.text
)
def test_no_stem_no_run(self, store):
assert descriptor_runs(store, "99491") == []
def test_max_elements_cap(self, store):
run = descriptor_runs(store, "99490", max_elements=2)[0]
assert [p.p_id for p in run.elements] == [1245, 1246]
def test_enumeration_list_item_is_not_a_descriptor_stem(self, store):
# C1 live-corpus incident: "( 9) 99439 (code for non-complex
# chronic care management)." reads like a stem ("99439 (") but is
# an enumeration/cross-reference line, not the opening of 99439's
# own descriptor.
store.con.executemany(
"INSERT INTO fr_anchors VALUES (?,?,?,?,?)",
[
(
"DE2VH9PD",
1300,
67800,
1300,
"( 9) 99439 (code for non-complex chronic care management).",
),
(
"DE2VH9PD",
1301,
67800,
1301,
"( 10) 99457 and 99458 (codes for remote physiologic monitoring).",
),
],
)
assert descriptor_runs(store, "99439") == []
def test_lowercase_stem_still_matches(self):
# `_stem_pattern` stays case-insensitive: some rules print the
# descriptor lowercase.
s = _Store()
s.con.execute(
"INSERT INTO items VALUES ('AAAAAAAA', 'Medicare Program; CY 2021 PFS Final Rule', '2020-11-13')"
)
s.con.executemany(
"INSERT INTO fr_anchors VALUES (?,?,?,?,?)",
[
(
"AAAAAAAA",
1,
100,
1,
"CPT code 99490 (chronic care management services, at least 20 "
"minutes of clinical staff time directed by a physician or other "
"qualified health care professional, per calendar month, with the "
"following required elements:",
),
("AAAAAAAA", 2, 100, 2, "Consent;"),
],
)
try:
runs = descriptor_runs(s, "99490")
assert len(runs) == 1
finally:
s.close()
class TestDuckDBSources:
def test_long_description(self, con):
assert hcpcs_long_description(con, "G0556").startswith("Advanced primary care")
assert hcpcs_long_description(con, "99490") == ""
def test_long_description_deterministic_seqnum(self, con):
# With multiple rows for same hcpcs, ORDER BY seqnum DESC picks the highest
result = hcpcs_long_description(con, "G0556")
assert (
result == "Advanced primary care management services … per calendar month"
)
def test_rvu_descriptions_base_rows_only(self, con):
assert rvu_descriptions(con, "99490") == [
(2015, "A", "Chron care mgmt srvc 20 min"),
(2022, "A", "Chrnc care mgmt staff 1st 20"),
]