fix: rekey 10,236 invalid bib.sqlite keys to Zotero charset, convert CCLF cites
Some checks failed
CI / lint-test (push) Failing after 1m25s
CI / skinny-install (aco) (push) Successful in 52s
CI / skinny-install (api) (push) Successful in 27s
CI / skinny-install (bcda) (push) Successful in 36s
CI / skinny-install (bib) (push) Successful in 36s
CI / skinny-install (bls) (push) Successful in 28s
CI / skinny-install (ccw) (push) Successful in 31s
CI / skinny-install (cms) (push) Successful in 27s
CI / skinny-install (cli) (push) Successful in 36s
CI / skinny-install (conf) (push) Successful in 30s
CI / skinny-install (api) (pull_request) Successful in 32s
CI / skinny-install (bcda) (pull_request) Successful in 34s
CI / skinny-install (bls) (pull_request) Successful in 29s
CI / skinny-install (bib) (pull_request) Successful in 42s
CI / skinny-install (ccw) (pull_request) Successful in 29s
CI / skinny-install (opps) (push) Successful in 30s
CI / skinny-install (perf) (push) Successful in 32s
CI / skinny-install (pfs) (push) Successful in 34s
CI / skinny-install (rex) (push) Successful in 33s
CI / lint-test (pull_request) Failing after 1m22s
CI / skinny-install (aco) (pull_request) Successful in 1m1s
CI / skinny-install (cli) (pull_request) Successful in 32s
CI / skinny-install (cms) (pull_request) Successful in 30s
CI / skinny-install (conf) (pull_request) Successful in 30s
CI / skinny-install (rex) (pull_request) Successful in 26s
Infra CI / zotero (push) Successful in 6s
Infra CI / mc (push) Successful in 6s
Infra CI / notebooks (pull_request) Successful in 6s
Infra CI / zotero (pull_request) Successful in 6s
Infra CI / docs (pull_request) Failing after 6s
CI / skinny-install (opps) (pull_request) Successful in 26s
CI / skinny-install (perf) (pull_request) Successful in 33s
CI / skinny-install (pfs) (pull_request) Successful in 27s
Infra CI / notebooks (push) Successful in 7s
Infra CI / docs (push) Failing after 8s
Infra CI / api (push) Successful in 8s
Infra CI / api (pull_request) Successful in 9s
Infra CI / mc (pull_request) Successful in 7s

Two changes:

1. Rekeyed all bib.sqlite items/attachments with chars outside the
   Zotero charset (23456789ABCDEFGHIJKLMNPQRSTUVWXYZ). Chars 0, 1, O, L
   are not valid in Zotero keys. 10,236 items + 1,881 attachments fixed.

2. Converted all 30 CCLF IP Section freeform citations in
   aco/express/cclf.py to structured :pincite: directives:
     Before: CCLF IP Section 3.1 "Matching MBIs" (p.14):
     After:  :pincite:`VTWVB384 §3.1 p.14` — Matching MBIs:

Updated tests to verify pincite parsing instead of meta: tag extraction
from the now-converted docstrings.

fixes #302
This commit is contained in:
kert
2026-03-27 01:14:10 -04:00
parent 7db84dce62
commit c0ddf54c31
3 changed files with 41 additions and 39 deletions

View File

@@ -85,7 +85,7 @@ def stg_beneficiary_xref(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 3.1 "Matching MBIs" (p.14):
:pincite:`VTWVB384 §3.1 p.14` — Matching MBIs:
"A beneficiary's MBI is unique to that beneficiary but may change
over time. CCLFs 1 through 9, A, and B, as they are provided each
@@ -94,7 +94,7 @@ def stg_beneficiary_xref(
can be used each month to cross reference records associated with the
current MBI to records associated with previous MBIs."
CCLF IP Section 5.1.1 "Creation of the Most Recent MBI field" (p.19):
:pincite:`VTWVB384 §5.1.1 p.19` — Creation of the Most Recent MBI field:
"The beneficiary XREF file (CCLF9) contains a complete history of
MBIs ever used to identify a beneficiary, for beneficiaries who have
@@ -129,7 +129,7 @@ def stg_institutional_header(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2.1 "Part A Claims Header File" (p.8-9):
:pincite:`VTWVB384 §2.2.1 p.8-9` — Part A Claims Header File:
"The Part A Claims Header File (CCLF1) contains header-level claim
information for institutional services covered by Part A and some
@@ -141,7 +141,7 @@ def stg_institutional_header(
MBI resolution: BENE_MBI_ID is joined to CCLF9._stg_beneficiary_xref
on PRVS_NUM to resolve to CURRENT_BENE_MBI_ID via COALESCE.
CCLF IP Section 5.3.1 "Calculating Total Part A and B Expenditures" (p.23):
:pincite:`VTWVB384 §5.3.1 p.23` — Calculating Total Part A and B Expenditures:
"Identify the canceled claims in the Part A Header file. These claims
are identified by CLM_ADJSMT_TYPE_CD=1. Change the sign of the
@@ -179,7 +179,7 @@ def int_institutional_header_adr(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 4.4 "Debit/Credit Method" (p.19):
:pincite:`VTWVB384 §4.4 p.19` — Debit/Credit Method:
"The Debit/Credit method gives a full account/history of claims
processed over time. The variable CLM_ADJSMT_TYPE_CD identifies:
@@ -187,12 +187,12 @@ def int_institutional_header_adr(
1 = Cancellation Claim
2 = Adjustment Claim (adjustment to an original claim)"
CCLF IP Section 5.1.2 "Natural Key for Part A" (p.20):
:pincite:`VTWVB384 §5.1.2 p.20` — Natural Key for Part A:
Part A natural key: CLM_BLG_PRVDR_OSCAR_NUM, CLM_FROM_DT,
CLM_THRU_DT, Most Recent MBI (MR_MBI).
CCLF IP Section 5.2.1 "Related Claims in Part A Header File" (p.21-22):
:pincite:`VTWVB384 §5.2.1 p.21-22` — Related Claims in Part A Header File:
"This group of claims consists of records that are all related to one
another — they all involve a claim for services provided to a
@@ -235,7 +235,7 @@ def stg_revenue_center(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2.2 "Part A Claim Revenue Center Detail File" (p.9):
:pincite:`VTWVB384 §2.2.2 p.9` — Part A Claim Revenue Center Detail File:
"The Part A Claims Revenue Center Detail File (CCLF2) contains
line-item level detail for each claim from the Part A Claims Header
@@ -243,7 +243,7 @@ def stg_revenue_center(
service was received, and for outpatient claims the payment amount
and allowed charge amount for individual services."
CCLF IP Section 3.5 "Part A Header vs Revenue Center Expenditures" (p.16):
:pincite:`VTWVB384 §3.5 p.16` — Part A Header vs Revenue Center Expenditures:
"Both the Part A Header file (CCLF1) and the Part A Revenue Center
file (CCLF2) contain a payment field (CLM_PMT_AMT and
@@ -282,7 +282,7 @@ def int_diagnosis_pivot(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2.4 "Part A Diagnosis Code File" (p.9):
:pincite:`VTWVB384 §2.2.4 p.9` — Part A Diagnosis Code File:
"The Part A Diagnosis Code File (CCLF4) contains the diagnosis code
for the principal diagnosis as well as all secondary diagnoses that
@@ -336,7 +336,7 @@ def int_procedure_pivot(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2.3 "Part A Procedure Code File" (p.9):
:pincite:`VTWVB384 §2.2.3 p.9` — Part A Procedure Code File:
"The Part A Procedure Code File (CCLF3) contains detailed information
regarding claims from the Part A Claims Header File, such as the type
@@ -402,7 +402,7 @@ def int_institutional_medical_claim(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2 "Part A Claims Data" (p.8):
:pincite:`VTWVB384 §2.2 p.8` — Part A Claims Data:
"Part A claim data files contain claims submitted by facilities such
as hospitals, SNFs, HHAs, rehabilitation facilities, and dialysis
@@ -560,7 +560,7 @@ def stg_physician_claim(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2.6 "Part B Physician File" (p.10):
:pincite:`VTWVB384 §2.2.6 p.10` — Part B Physician File:
"The Part B Physician File (CCLF5) consists of claim-line records but
includes both claim-level and line-level information. At the claim
@@ -570,7 +570,7 @@ def stg_physician_claim(
amount, allowed charge amount, line-level diagnosis code, units of
service, primary payer, provider TIN, and rendering NPI number."
CCLF IP Section 5.3.1 (p.23):
:pincite:`VTWVB384 §5.3.1 p.23` — Section 5.3.1:
"Identify all the canceled records (line items) in the Part B
Physician file. The canceled line items are identified by
@@ -603,16 +603,16 @@ def int_physician_claim_adr(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 5.1.2 "Natural Key for Part B Physician/DME" (p.20):
:pincite:`VTWVB384 §5.1.2 p.20` — Natural Key for Part B Physician/DME:
Part B natural key: CLM_CNTL_NUM, Most Recent MBI (MR_MBI).
CCLF IP Section 5.2.2 "Related Claims in the Part B Physician File" (p.22):
:pincite:`VTWVB384 §5.2.2 p.22` — Related Claims in the Part B Physician File:
"In the Part B Physician File, you will find original claims,
cancellation claims, and adjustment claims."
CCLF IP Section 3.2 "Dropping Denied Claims" (p.15):
:pincite:`VTWVB384 §3.2 p.15` — Dropping Denied Claims:
"For Part B Physician/DME claims, some individual line-items can be
denied, whereas other line-items are not denied. Part B claims need
@@ -652,7 +652,7 @@ def int_physician_medical_claim(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2.6 "Part B Physician File" (p.10):
:pincite:`VTWVB384 §2.2.6 p.10` — Part B Physician File:
CCLF5 contains both claim-level and line-level data in a single
file. Unlike Part A (which has separate header/line/dx/px files),
@@ -763,7 +763,7 @@ def stg_dme_claim(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2.7 "Part B DME File" (p.10):
:pincite:`VTWVB384 §2.2.7 p.10` — Part B DME File:
"The Part B DME File (CCLF6) consists of claim-line records but
includes both claim-level and line-level information. Claim-level
@@ -773,7 +773,7 @@ def stg_dme_claim(
amount, ordering NPI number, and 'paid to' NPI number."
Cancellation adjustment applied to CLM_LINE_CVRD_PD_AMT and
CLM_LINE_ALOWD_CHRG_AMT per IP Section 5.3.1.
CLM_LINE_ALOWD_CHRG_AMT per :pincite:`VTWVB384 §5.3.1` —
"""
xref = cclf___stg_beneficiary_xref
return cclf__cclf6.join(
@@ -799,7 +799,7 @@ def int_dme_claim_adr(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 5.2.3 "Related Claims in the Part B DME File" (p.23):
:pincite:`VTWVB384 §5.2.3 p.23` — Related Claims in the Part B DME File:
"In the Part B DME File, you will find original claims, cancellation
claims, and adjustment claims. A variety of related claims are found
@@ -840,7 +840,7 @@ def int_dme_medical_claim(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2.7 "Part B DME File" (p.10):
:pincite:`VTWVB384 §2.2.7 p.10` — Part B DME File:
Key field mappings from CCLF6 (IP Table 19):
- CUR_CLM_UNIQ_ID -> claim_id
@@ -940,7 +940,7 @@ def medical_claim(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.2 "Part A Claims Data" + Section 2.2.6-2.2.7 (p.8-10):
:pincite:`VTWVB384 §2.2 p.8-10` — Part A Claims Data:
The three claim types are combined into a single medical_claim table:
@@ -954,7 +954,7 @@ def medical_claim(
- Professional/DME (CCLF6): Durable Medical Equipment, Prosthetics,
Orthotics, and Supplies. claim_type = 'professional'.
CCLF IP Section 5.4 "Part A vs Part B Claims" (p.27):
:pincite:`VTWVB384 §5.4 p.27` — Part A vs Part B Claims:
"The Part A claims files will include Medicare provider payments for
some services covered under both Part A and Part B. To distinguish,
@@ -984,7 +984,7 @@ def stg_pharmacy_claim(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.3 "Part D Claims Data" (p.10):
:pincite:`VTWVB384 §2.3 p.10` — Part D Claims Data:
"The Part D File (CCLF7) contains prescription drug information at
the beneficiary level. Data elements include the NDC, quantity
@@ -1015,7 +1015,7 @@ def int_pharmacy_claim_adr(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 3.3 "Part D Data Limitations" (p.15):
:pincite:`VTWVB384 §3.3 p.15` — Part D Data Limitations:
"The Part D claims contained in the CCLF are 'final action' claims,
unlike the other claims-related files which are debit/credit claims.
@@ -1025,7 +1025,7 @@ def int_pharmacy_claim_adr(
for any given set of Related Claims the most recent claim and
delete/ignore all of the previous related claims for that event."
CCLF IP Section 5.2.4 "Related Claims in the Part D File" (p.23):
:pincite:`VTWVB384 §5.2.4 p.23` — Related Claims in the Part D File:
"In the Part D File, you will find original claims, cancellation
claims, and adjustment claims."
@@ -1057,7 +1057,7 @@ def pharmacy_claim(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.3 "Part D Claims Data" (p.10):
:pincite:`VTWVB384 §2.3 p.10` — Part D Claims Data:
Key field mappings from CCLF7 (IP Table 20):
- CUR_CLM_UNIQ_ID -> claim_id
@@ -1137,14 +1137,14 @@ def stg_beneficiary_demographics(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.4.1 "Beneficiary Demographics File" (p.10-12):
:pincite:`VTWVB384 §2.4.1 p.10-12` — Beneficiary Demographics File:
"This file contains the beneficiary's current MBI, first/middle/last
name, ZIP code, date of birth, sex, race, age, Medicare Status Code,
dual eligibility status, hospice begin/end dates, and date of death
if a decedent."
CCLF IP Section 3.1 (p.14):
:pincite:`VTWVB384 §3.1 p.14` — Section 3.1:
MBI resolution via CCLF9 applied before deduplication to ensure a
single row per resolved beneficiary identity.
@@ -1181,7 +1181,7 @@ def eligibility(
CCLF IP Reference
~~~~~~~~~~~~~~~~~~
CCLF IP Section 2.4.1 "Beneficiary Demographics File" (p.10):
:pincite:`VTWVB384 §2.4.1 p.10` — Beneficiary Demographics File:
Key field mappings from CCLF8 (IP Table 21):
- BENE_MBI_ID (resolved) -> person_id, member_id

View File

@@ -48,7 +48,7 @@ if TYPE_CHECKING:
# Zotero key charset: 23456789ABCDEFGHIJKLMNPQRSTUVWXYZ (no 0, 1, O, L)
_PINCITE_RE = re.compile(
r":pincite:`"
r"([23456789A-HJ-NP-Z]{8})" # group 1: item key
r"([23456789A-HJ-NP-Z]{8})" # group 1: item key (strict Zotero charset)
r"(?:\s+(.+?))?" # group 2: locator (optional)
r"`"
r"(?:\s*(?:--|—)\s*(.+))?" # group 3: note (optional)

View File

@@ -113,12 +113,15 @@ class TestExtractMetaTags:
assert extract_meta_tags(fn) == []
def test_real_cclf_function(self):
"""CCLF functions now use :pincite: directives instead of bare CCLF IP Section refs."""
from aco.express.cclf import stg_beneficiary_xref
from bib.pincite import parse_pincites
tags = extract_meta_tags(stg_beneficiary_xref)
labels = {t.label for t in tags}
assert "meta:cclf-ip-s3.1" in labels
assert "meta:cclf-ip-s5.1.1" in labels
doc = stg_beneficiary_xref.__doc__ or ""
pincites = parse_pincites(doc, "aco.express.cclf.stg_beneficiary_xref")
assert len(pincites) >= 2
keys = {p.item_key for p in pincites}
assert "VTWVB384" in keys
# ── extract_meta_details ──────────────────────────────────────────
@@ -269,6 +272,7 @@ class TestTagItemsFromPipeline:
store = Store(":memory:")
item = Source(
key="VTWVB384",
title="CCLF Information Packet",
tags=["source:cms-cclf-ip", "module:aco"],
)
@@ -282,12 +286,10 @@ class TestTagItemsFromPipeline:
tagged = {k: v for k, v in report.items() if v}
assert len(tagged) > 0
# Verify the item now has fn: and meta: tags
# Verify the item now has fn: tags (meta: tags replaced by :pincite: directives)
updated = store.get(key)
fn_tags = [t for t in updated.tags if t.startswith("fn:")]
meta_tags = [t for t in updated.tags if t.startswith("meta:")]
assert len(fn_tags) > 0
assert len(meta_tags) > 0
# ── generate_docstring_refs ───────────────────────────────────────