Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7c6e0e5
Rebase to cherry-pick remove commits not intended for this branch and…
jonathan-cantu-icf Apr 29, 2026
02bf75b
More updates - primarily to pyproject.toml files.
jonathan-cantu-icf Apr 29, 2026
96f6c93
Add filters for pytest and ruff for projects not included in uv root …
jonathan-cantu-icf Apr 8, 2026
c0003dc
Cleanup around projects that seem to be failing in CI.
jonathan-cantu-icf Apr 8, 2026
22a0258
More dissection and consolidation of dependencies as appropriate. Try…
jonathan-cantu-icf Apr 9, 2026
705b6e8
Second try on getting 'locust_tests' to pass ruff checks and spawning…
jonathan-cantu-icf Apr 9, 2026
6b19ec7
Fix Pyright error 'key' is not a known attribute of 'None'.
jonathan-cantu-icf Apr 9, 2026
8c5f38b
Fix Pyright error 'key' is not a known attribute of 'None'.
jonathan-cantu-icf Apr 9, 2026
278fedf
Fix Pyright test dependency issue.
jonathan-cantu-icf Apr 9, 2026
f4fe814
Fix Pyright test dependency issue (2nd attempt).
jonathan-cantu-icf Apr 9, 2026
ed4cd1b
Fix Pyright test dependency issue (2nd attempt).
jonathan-cantu-icf Apr 9, 2026
d6d4f16
Fix a syntax error in pyproject.toml for samsha-regression-tests.
jonathan-cantu-icf Apr 9, 2026
ea0c191
Fix a organized imports formatting issue.
jonathan-cantu-icf Apr 9, 2026
3a0c379
More updates - primarily to pyproject.toml files.
jonathan-cantu-icf Apr 29, 2026
e4f2a68
Fix ruff check for all remaining Python projects under BFD repo.
jonathan-cantu-icf Apr 23, 2026
9f1755f
Save current state of branch.
jonathan-cantu-icf Apr 7, 2026
0d91a36
Cleanup and reduce scope to only Python 3.13 projects as a root uv wo…
jonathan-cantu-icf Apr 7, 2026
6c7c280
More dissection and consolidation of dependencies as appropriate. Try…
jonathan-cantu-icf Apr 9, 2026
7c7c2a4
Cleanup and catch up with related branch for BFD-4654.
jonathan-cantu-icf Apr 23, 2026
48587a1
Latest updates and Ruff fixes.
jonathan-cantu-icf Apr 24, 2026
d0a5a42
Undo excludes for Pyright - so that we can clean that up.
jonathan-cantu-icf Apr 24, 2026
2846a99
Save current state of branch.
jonathan-cantu-icf Apr 7, 2026
0d1a6aa
Cleanup and reduce scope to only Python 3.13 projects as a root uv wo…
jonathan-cantu-icf Apr 7, 2026
f279f1b
More dissection and consolidation of dependencies as appropriate. Try…
jonathan-cantu-icf Apr 9, 2026
5d5e1a7
Updates for root level pyproject.toml and uv.lock.
jonathan-cantu-icf Apr 27, 2026
caf1d42
Rebase and update merge conflicts.
jonathan-cantu-icf Apr 23, 2026
7bcd83f
Drop a python-version file downsteam.
jonathan-cantu-icf Apr 29, 2026
15666a5
Fix all new ruff errors after rebasing from master.
jonathan-cantu-icf May 1, 2026
50961b6
Final fixes for pyright errors.
jonathan-cantu-icf May 4, 2026
86b43e3
Alex says this file is no longer needed - unused.
jonathan-cantu-icf May 4, 2026
b9da609
Blow away the ci_python.xml. No longer necessary.
jonathan-cantu-icf May 4, 2026
b925fde
Fix Git CI error.
jonathan-cantu-icf May 4, 2026
105cf21
More fixes for Pyright.
jonathan-cantu-icf May 6, 2026
b9c70e3
Resolved more Pyright errors under and a few under
jonathan-cantu-icf May 7, 2026
16e2b41
Last few fixes for Pyright errors under 'apps/utils/locust_tests'.
jonathan-cantu-icf May 7, 2026
b9515f2
Fix for the timer import error from Pyright for loader.py.
jonathan-cantu-icf May 7, 2026
a2e5db3
Fix for the timer import error from Pyright for loader.py.
jonathan-cantu-icf May 7, 2026
29c4f8c
Fix for the timer import error from Pyright this time for extractor.py.
jonathan-cantu-icf May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 0 additions & 77 deletions .github/workflows/ci-python.yml

This file was deleted.

62 changes: 32 additions & 30 deletions apps/bfd-model-idr/augment_sample_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
from dataclasses import asdict, dataclass, field
from decimal import Decimal
from pathlib import Path
from typing import Optional
from datetime import datetime, timezone

import pandas as pd

Expand Down Expand Up @@ -89,26 +87,23 @@


def convert_to_decimal(val: str | None) -> Decimal:
try:
return Decimal(val)
except (TypeError, ValueError):
return 0.0
return Decimal(val or 0.0)

@dataclass
class Provider:
PRVDR_SK: Optional[str] = None
PRVDR_ID_QLFYR_CD: Optional[str] = None
NPI_TYPE: Optional[str] = None
careTeamType: Optional[str] = None
careTeamSequenceNumber: Optional[str] = None
PRVDR_LAST_OR_LGL_NAME: Optional[str] = None
PRVDR_1ST_NAME: Optional[str] = None
PRVDR_CARETEAM_NAME: Optional[str] = None
specialtyCode: Optional[str] = None
PRVDR_OSCAR_NUM: Optional[str] = None
CLM_BLG_PRVDR_ZIP5_CD: Optional[str] = None
CLM_PRVDR_GNRC_ID_NUM: Optional[str] = None
CLM_BLG_PRVDR_TAX_NUM: Optional[str] = None
PRVDR_SK: str | None = None
PRVDR_ID_QLFYR_CD: str | None = None
NPI_TYPE: str | None = None
careTeamType: str | None = None
careTeamSequenceNumber: str | None = None
PRVDR_LAST_OR_LGL_NAME: str | None = None
PRVDR_1ST_NAME: str | None = None
PRVDR_CARETEAM_NAME: str | None = None
specialtyCode: str | None = None
PRVDR_OSCAR_NUM: str | None = None
CLM_BLG_PRVDR_ZIP5_CD: str | None = None
CLM_PRVDR_GNRC_ID_NUM: str | None = None
CLM_BLG_PRVDR_TAX_NUM: str | None = None

populate_fields_except_na = [
"PRVDR_LGL_NAME",
Expand Down Expand Up @@ -202,13 +197,14 @@ def create_careteam_provider(careteam_column):
for careteam_column in careteam_header_columns:
if careteam_column not in cur_sample_data:
continue

provider_object = create_careteam_provider(careteam_column)
provider_object.careTeamSequenceNumber = sum(
1 for item in provider_list if provider_object.careTeamType
)

count = sum(1 for _ in provider_list if provider_object.careTeamType)
provider_object.careTeamSequenceNumber = str(count)

provider_list.append(provider_object)


# Distinct method since line items end up cleaner
def create_rendering_line_provider(npi_num):
provider_object = Provider(
Expand All @@ -235,11 +231,16 @@ def create_rendering_line_provider(npi_num):
provider = create_rendering_line_provider(prvdr_npi_num)
if line_item.get("CLM_RNDRG_FED_PRVDR_SPCLTY_CD"):
provider.specialtyCode = line_item.get("CLM_RNDRG_FED_PRVDR_SPCLTY_CD")
provider.careTeamSequenceNumber = sum(
1 for item in provider_list if provider_object.careTeamType
)
line_item["careTeamSequence"] = provider.careTeamSequenceNumber
provider_list.append(provider)

sequence_count = sum(
1 for _ in provider_list
if getattr(provider, "careTeamType", None)
)

provider.careTeamSequenceNumber = str(sequence_count)

line_item["careTeamSequence"] = provider.careTeamSequenceNumber
provider_list.append(provider)

if prvdr_npi_num:
sequence = next(
Expand All @@ -260,7 +261,8 @@ def create_rendering_line_provider(npi_num):
matching_rows = cond_sk_df[cond_sk_df["CLM_RLT_COND_SGNTR_SK"] == str(cond_sk)]
for _, row in matching_rows.iterrows():
cond_cd = row.get("CLM_RLT_COND_CD")
if pd.notna(cond_cd) and str(cond_cd) != "~":
# Use manual NaN check instead of pd.isna()
if cond_cd is not None and cond_cd == cond_cd and str(cond_cd) != "~":
supporting_info_components.append({"CLM_RLT_COND_CD": str(cond_cd)})

fac_type = cur_sample_data.get("CLM_BILL_FAC_TYPE_CD")
Expand Down Expand Up @@ -366,7 +368,7 @@ def build_claim_audit_trail_composite(sample: dict) -> str:
status = sample.get("CLM_AUDT_TRL_STUS_CD")

if not status:
return None
return ""

prefix = meta_src_prefix(meta_src_sk)

Expand Down
46 changes: 30 additions & 16 deletions apps/bfd-model-idr/claims_adj.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
AVAIL_CLM_RLT_COND_SK,
AVAIL_OSCAR_CODES_INSTITUTIONAL,
AVAILABLE_NDC,
AVAILABLE_SSA_STATE_CDS,
CLM_POA_IND_CHOICES,
FISS_CLM_TYPE_CDS,
HCPCS_MODS,
Expand All @@ -17,7 +18,6 @@
PHARMACY_CLM_TYPE_CDS,
TARGET_RLT_COND_CODES,
TARGET_SEQUENCE_NUMBERS,
AVAILABLE_SSA_STATE_CDS,
get_drg_dgns_codes,
get_hcpcs_proc_codes,
get_icd_10_dgns_codes,
Expand All @@ -42,16 +42,27 @@ class AdjudicatedGeneratorUtil:
def __init__(self, enable_samhsa: bool) -> None:
self.enable_samhsa = enable_samhsa

@staticmethod
def safe_random_choice(sequence, default=None):
"""Safely pick a random element from a sequence that might be None."""
if not sequence:
return default
return random.choice(sequence)

def gen_clm(
self,
gen_utils: GeneratorUtil,
bene_sk: str,
init_clm: RowAdapter | None = None,
min_date: str = "2018-01-01",
max_date: str = str(NOW),
type_1_npis: list = [0],
type_2_npis: list = [0],
type_1_npis: list | None = None,
type_2_npis: list | None = None,
):

self.type_1_npis = type_1_npis if type_1_npis is not None else [0]
self.type_2_npis = type_2_npis if type_2_npis is not None else [0]

clm = init_clm or RowAdapter({})
clm[f.CLM_DT_SGNTR_SK] = gen_basic_id(field=f.CLM_DT_SGNTR_SK, length=12)
clm[f.CLM_UNIQ_ID] = gen_basic_id(field=f.CLM_UNIQ_ID, length=13)
Expand Down Expand Up @@ -96,7 +107,7 @@ def gen_clm(
if clm_type_cd not in PHARMACY_CLM_TYPE_CDS:
clm[f.CLM_QUERY_CD] = random.choice(gen_utils.code_systems[f.CLM_QUERY_CD])
else:
clm[f.CLM_SRVC_PRVDR_GNRC_ID_NUM] = random.choice(type_2_npis)
clm[f.CLM_SRVC_PRVDR_GNRC_ID_NUM] = self.safe_random_choice(type_2_npis)
clm[f.PRVDR_SRVC_ID_QLFYR_CD] = random.choice(
gen_utils.code_systems[f.PRVDR_ID_QLFYR_CD]
)
Expand All @@ -105,7 +116,7 @@ def gen_clm(
clm[f.PRVDR_PRSBNG_ID_QLFYR_CD] = random.choice(
gen_utils.code_systems[f.PRVDR_ID_QLFYR_CD]
)
clm[f.CLM_PRSBNG_PRVDR_GNRC_ID_NUM] = random.choice(type_1_npis)
clm[f.CLM_PRSBNG_PRVDR_GNRC_ID_NUM] = self.safe_random_choice(type_1_npis)
clm[f.PRVDR_PRSCRBNG_PRVDR_NPI_NUM] = clm[f.CLM_PRSBNG_PRVDR_GNRC_ID_NUM]
clm[f.CLM_SBMT_CHRG_AMT] = round(random.uniform(1, 1000000), 2)
clm[f.CLM_SBMT_FRMT_CD] = random.choice(gen_utils.code_systems[f.CLM_SBMT_FRMT_CD])
Expand Down Expand Up @@ -138,26 +149,26 @@ def gen_clm(
clm[f.CLM_LTST_CLM_IND] = clm_ltst_clm_ind

if (clm_type_cd < 65 and clm_type_cd >= 10) or clm_type_cd in FISS_CLM_TYPE_CDS:
clm[f.PRVDR_BLG_PRVDR_NPI_NUM] = random.choice(type_2_npis)
clm[f.CLM_ATNDG_PRVDR_NPI_NUM] = random.choice(type_1_npis)
clm[f.PRVDR_BLG_PRVDR_NPI_NUM] = self.safe_random_choice(type_2_npis)
clm[f.CLM_ATNDG_PRVDR_NPI_NUM] = self.safe_random_choice(type_1_npis)
clm[f.PRVDR_ATNDG_PRVDR_NPI_NUM] = clm[f.CLM_ATNDG_PRVDR_NPI_NUM]
clm[f.CLM_OPRTG_FED_PRVDR_SPCLTY_CD] = random.choice(
gen_utils.code_systems[f.CLM_PRVDR_SPCLTY_CD]
)
clm[f.CLM_OPRTG_PRVDR_NAME] = random.choice(["Random last, First", "~"])
clm[f.CLM_OPRTG_PRVDR_NPI_NUM] = random.choice(type_1_npis)
clm[f.CLM_OPRTG_PRVDR_NPI_NUM] = self.safe_random_choice(type_1_npis)
clm[f.PRVDR_OPRTG_PRVDR_NPI_NUM] = clm[f.CLM_OPRTG_PRVDR_NPI_NUM]
clm[f.CLM_OTHR_FED_PRVDR_SPCLTY_CD] = random.choice(
gen_utils.code_systems[f.CLM_PRVDR_SPCLTY_CD]
)
clm[f.CLM_OTHR_PRVDR_NAME] = random.choice(["Random last, First", "~"])
clm[f.CLM_OTHR_PRVDR_NPI_NUM] = random.choice(type_1_npis)
clm[f.CLM_OTHR_PRVDR_NPI_NUM] = self.safe_random_choice(type_1_npis)
clm[f.PRVDR_OTHR_PRVDR_NPI_NUM] = clm[f.CLM_OTHR_PRVDR_NPI_NUM]
clm[f.CLM_RNDRG_FED_PRVDR_SPCLTY_CD] = random.choice(
gen_utils.code_systems[f.CLM_PRVDR_SPCLTY_CD]
)
clm[f.CLM_RNDRG_PRVDR_NAME] = random.choice(["Random last, First", "~"])
clm[f.CLM_RNDRG_PRVDR_NPI_NUM] = random.choice(type_1_npis)
clm[f.CLM_RNDRG_PRVDR_NPI_NUM] = self.safe_random_choice(type_1_npis)
clm[f.PRVDR_RNDRNG_PRVDR_NPI_NUM] = clm[f.CLM_RNDRG_PRVDR_NPI_NUM]
clm[f.CLM_ATNDG_FED_PRVDR_SPCLTY_CD] = random.choice(
gen_utils.code_systems[f.CLM_PRVDR_SPCLTY_CD]
Expand All @@ -184,12 +195,12 @@ def gen_clm(
clm[f.CLM_ACO_CARE_MGMT_HCBS_SW] = "Y" if "7" in used_enhancements else "N"

if clm_type_cd == 40 or (clm_type_cd > 70 and clm_type_cd <= 82):
clm[f.PRVDR_RFRG_PRVDR_NPI_NUM] = random.choice(type_1_npis)
clm[f.PRVDR_RFRG_PRVDR_NPI_NUM] = self.safe_random_choice(type_1_npis)
if clm_type_cd > 70 and clm_type_cd <= 82:
clm[f.CLM_BLG_PRVDR_NPI_NUM] = random.choice(type_1_npis)
clm[f.CLM_BLG_PRVDR_NPI_NUM] = self.safe_random_choice(type_1_npis)
clm[f.CLM_RLT_COND_SGNTR_SK] = "0"
if random.choice([0, 1]):
clm[f.CLM_BLG_PRVDR_NPI_NUM] = random.choice(type_2_npis)
clm[f.CLM_BLG_PRVDR_NPI_NUM] = self.safe_random_choice(type_2_npis)
clm[f.PRVDR_BLG_PRVDR_NPI_NUM] = clm[f.CLM_BLG_PRVDR_NPI_NUM]

# generate claim header financial elements here
Expand Down Expand Up @@ -744,8 +755,11 @@ def gen_clm_line(
clm_line_num: int,
diagnoses: list[RowAdapter],
init_clm_line: RowAdapter | None = None,
type_1_npis: list = [0],
type_1_npis: list | None = None,
):

self.type_1_npis = type_1_npis if type_1_npis is not None else [0]

clm_type_cd = int(clm[f.CLM_TYPE_CD])
clm_line = init_clm_line or RowAdapter({})
clm_line[f.GEO_BENE_SK] = clm[f.GEO_BENE_SK]
Expand Down Expand Up @@ -781,7 +795,7 @@ def gen_clm_line(
if clm_type_cd >= 71 and clm_type_cd <= 72:
clm_line[f.CLM_RNDRG_PRVDR_TAX_NUM] = random.choice(["1928347912", "912834729"])
clm_line[f.CLM_RNDRG_PRVDR_PIN_NUM] = random.choice(["29364819", "19238747"])
clm_line[f.PRVDR_RNDRNG_PRVDR_NPI_NUM] = random.choice(type_1_npis)
clm_line[f.PRVDR_RNDRNG_PRVDR_NPI_NUM] = self.safe_random_choice(type_1_npis)
clm_line[f.CLM_RNDRG_PRVDR_NPI_NUM] = clm_line[f.PRVDR_RNDRNG_PRVDR_NPI_NUM]
clm_line[f.CLM_RNDRG_FED_PRVDR_SPCLTY_CD] = random.choice(
gen_utils.code_systems[f.CLM_PRVDR_SPCLTY_CD]
Expand Down Expand Up @@ -811,7 +825,7 @@ def gen_clm_line(
)

if clm_type_cd == 81 or clm_type_cd == 82:
clm_line[f.PRVDR_RNDRNG_PRVDR_NPI_NUM] = random.choice(type_1_npis)
clm_line[f.PRVDR_RNDRNG_PRVDR_NPI_NUM] = self.safe_random_choice(type_1_npis)
clm_line[f.CLM_RNDRG_PRVDR_NPI_NUM] = clm_line[f.PRVDR_RNDRNG_PRVDR_NPI_NUM]

clm_line[f.CLM_LINE_HCPCS_CD] = random.choice(get_hcpcs_proc_codes(self.enable_samhsa))
Expand Down
Loading