Some checks failed
CI / skinny-install (aco) (push) Successful in 45s
CI / skinny-install (api) (push) Successful in 29s
CI / skinny-install (bcda) (push) Successful in 25s
CI / skinny-install (bib) (push) Successful in 23s
CI / skinny-install (bls) (push) Successful in 20s
CI / skinny-install (ccw) (push) Successful in 36s
CI / skinny-install (cli) (push) Successful in 27s
CI / skinny-install (cms) (push) Successful in 24s
CI / skinny-install (conf) (push) Successful in 27s
CI / skinny-install (pfs) (push) Successful in 25s
CI / skinny-install (rex) (push) Successful in 25s
CI / lint-test (push) Successful in 6m2s
Infra CI / notebooks (push) Successful in 7s
Infra CI / zotero (push) Failing after 6s
Infra CI / docs (push) Successful in 33s
Infra CI / api (push) Successful in 6s
Infra CI / mc (push) Successful in 7s
Deploy / build-scan-report (push) Has been cancelled
- Fix all 72 ruff lint errors (unused imports, unused variables, E402) - Format all 14 unformatted dev/scripts files - Move generated artifacts to assets/ (dag.html, pfs.html) - Remove duplicate root coverage.svg (already in assets/icons/) - Update .dockerignore for infra/ tree layout - Update .gitignore: add .env.bak, mirrors/, htmlcov/ - Fix stale path refs in coverage_badge.py, woodpecker backend, test_network_isolation.sh, docs custom.css - Add .gitkeep to empty dirs (infra/polaris, cloud/*/terraform) - Delete 12 stale local branches, 10 stale remote branches
941 lines
33 KiB
Python
941 lines
33 KiB
Python
"""Generate ACO REACH SQLTable models from the PY2023 Reporting and Data Sharing Overview PDF.
|
|
|
|
Parses all ACO REACH report specifications from the PY2023 ACO REACH Reporting
|
|
and Data Sharing Overview PDF to extract:
|
|
- Alignment file tables (PAE, BAR, PAR, PPO, SVA)
|
|
- Finance file tables (QBR, APA, MER, RSR)
|
|
- Quality file tables (QQR, AQR)
|
|
|
|
Generates Python modules at:
|
|
- src/aco/table/reach_alignment.py - Alignment report tables
|
|
- src/aco/table/reach_finance.py - Finance report tables
|
|
- src/aco/table/reach_quality.py - Quality report tables
|
|
- src/aco/table/reach_filenames.py - Filename pattern classifiers for rex
|
|
|
|
Usage::
|
|
|
|
uv run python dev/scripts/generate_reach_models.py
|
|
|
|
Source: dev/PY2023 ACO REACH Reporting and Data Sharing Overview_v20232203.pdf
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
# Define all table specifications based on extracted data dictionary
|
|
|
|
# ============================================================================
|
|
# ALIGNMENT TABLES
|
|
# ============================================================================
|
|
|
|
ALIGNMENT_TABLES = {
|
|
"preliminary_alignment_estimate": {
|
|
"class_name": "ReachPreliminaryAlignmentEstimate",
|
|
"description": "Provisional count of beneficiaries aligned by source",
|
|
"fields": [
|
|
("aco_identifier", "str", "5-character ACO ID"),
|
|
(
|
|
"provisionally_aligned_count",
|
|
"int",
|
|
"Total count of aligned beneficiaries",
|
|
),
|
|
(
|
|
"aligned_claims_only",
|
|
"int",
|
|
"Claims-based alignment count",
|
|
),
|
|
(
|
|
"aligned_voluntary_only",
|
|
"int",
|
|
"Voluntary alignment count (signed or electronic)",
|
|
),
|
|
(
|
|
"aligned_both",
|
|
"int",
|
|
"Both claims and voluntary alignment count",
|
|
),
|
|
],
|
|
},
|
|
"beneficiary_alignment_overview": {
|
|
"class_name": "ReachBeneficiaryAlignmentOverview",
|
|
"description": "Monthly year-to-date list of aligned beneficiaries - Overview worksheet",
|
|
"fields": [
|
|
("beneficiary_mbi_id", "str", "Medicare Beneficiary Identifier"),
|
|
(
|
|
"beneficiary_alignment_effective_start_date",
|
|
"date",
|
|
"Alignment start date (YYYYMMDD)",
|
|
),
|
|
(
|
|
"beneficiary_alignment_effective_termination_date",
|
|
"date | None",
|
|
"Alignment end date if applicable (YYYYMMDD)",
|
|
),
|
|
("beneficiary_first_name", "str", "First name"),
|
|
("beneficiary_last_name", "str", "Last name"),
|
|
("beneficiary_line_1_address", "str | None", "Address line 1"),
|
|
("beneficiary_line_2_address", "str | None", "Address line 2"),
|
|
("beneficiary_line_3_address", "str | None", "Address line 3"),
|
|
("beneficiary_line_4_address", "str | None", "Address line 4"),
|
|
("beneficiary_line_5_address", "str | None", "Address line 5"),
|
|
("beneficiary_line_6_address", "str | None", "Address line 6"),
|
|
("beneficiary_city", "str", "City of residence"),
|
|
("beneficiary_usps_state_code", "str", "State code"),
|
|
("beneficiary_zip_5", "str", "5-digit zip code"),
|
|
("beneficiary_zip_4", "str | None", "4-digit zip extension"),
|
|
(
|
|
"beneficiary_state_county_residence_ssa",
|
|
"str",
|
|
"SSA state-county code",
|
|
),
|
|
(
|
|
"beneficiary_state_county_residence_fips",
|
|
"str",
|
|
"FIPS county code",
|
|
),
|
|
("beneficiary_gender", "str", "M, F, or U"),
|
|
("beneficiary_race_ethnicity", "str", "Race/ethnicity category"),
|
|
("beneficiary_birth_date", "date", "Date of birth (YYYYMMDD)"),
|
|
("beneficiary_age", "int", "Age"),
|
|
(
|
|
"beneficiary_date_of_death",
|
|
"date | None",
|
|
"Death date if applicable (YYYYMMDD)",
|
|
),
|
|
(
|
|
"beneficiary_eligibility_alignment_year_1",
|
|
"str",
|
|
"Y/N - Year 1 eligibility flag",
|
|
),
|
|
(
|
|
"beneficiary_eligibility_alignment_year_2",
|
|
"str",
|
|
"Y/N - Year 2 eligibility flag",
|
|
),
|
|
(
|
|
"beneficiary_any_part_d_coverage_alignment_year_1",
|
|
"str",
|
|
"Y/N - Part D coverage year 1",
|
|
),
|
|
(
|
|
"beneficiary_any_part_d_coverage_alignment_year_2",
|
|
"str",
|
|
"Y/N - Part D coverage year 2",
|
|
),
|
|
(
|
|
"newly_aligned_beneficiary_flag",
|
|
"str",
|
|
"Y/N - New alignment indicator",
|
|
),
|
|
(
|
|
"prospective_plus_alignment",
|
|
"str",
|
|
"Y/N - Prospective Plus flag",
|
|
),
|
|
(
|
|
"claim_based_alignment_indicator",
|
|
"str",
|
|
"Y/N - Claims-based alignment",
|
|
),
|
|
(
|
|
"voluntary_alignment_type",
|
|
"str",
|
|
"Paper/Electronic/No - Voluntary alignment type",
|
|
),
|
|
(
|
|
"mobility_impairment_indicator",
|
|
"str",
|
|
"Y/N - High Needs Population indicator",
|
|
),
|
|
(
|
|
"frailty_indicator",
|
|
"str",
|
|
"Y/N - High Needs Population indicator",
|
|
),
|
|
(
|
|
"high_risk_score_indicator",
|
|
"str",
|
|
"Y/N - High Needs Population indicator",
|
|
),
|
|
(
|
|
"medium_risk_with_unplanned_admissions_indicator",
|
|
"str",
|
|
"Y/N - High Needs Population indicator",
|
|
),
|
|
],
|
|
},
|
|
"beneficiary_alignment_monthly": {
|
|
"class_name": "ReachBeneficiaryAlignmentMonthly",
|
|
"description": "Monthly beneficiary alignment status - Monthly worksheet",
|
|
"fields": [
|
|
("beneficiary_mbi_id", "str", "Medicare Beneficiary Identifier"),
|
|
("beneficiary_date_of_birth", "date", "Date of birth (YYYYMMDD)"),
|
|
("calendar_month", "str", "Calendar month (YYYYMM format)"),
|
|
("part_d_prescription_indicator", "str", "Y/N - Part D coverage"),
|
|
(
|
|
"medical_data_sharing_preference",
|
|
"str",
|
|
"Y/N - Data sharing preference",
|
|
),
|
|
(
|
|
"administrative_suppression",
|
|
"str",
|
|
"Y/N - Administrative suppression",
|
|
),
|
|
(
|
|
"alignment_status",
|
|
"str",
|
|
"AL/DD/DY/AB/MS/MC/CO/OU/EM/EP/NV - Status code",
|
|
),
|
|
],
|
|
},
|
|
"provider_alignment_report": {
|
|
"class_name": "ReachProviderAlignmentReport",
|
|
"description": "Provider-beneficiary alignment details with service charges",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO identifier"),
|
|
("mbi_id", "str", "Beneficiary's current MBI"),
|
|
("algn_type_clm", "str", "Y/N - Claims alignment indicator"),
|
|
(
|
|
"algn_type_va",
|
|
"str",
|
|
"SVA/EVA - Voluntary alignment type (Signed or Electronic)",
|
|
),
|
|
(
|
|
"prvdr_tin_num",
|
|
"str",
|
|
"TIN of billing practice or VA TIN",
|
|
),
|
|
(
|
|
"prvdr_npi_num",
|
|
"str",
|
|
"Provider NPI (renderer or voluntary alignment NPI)",
|
|
),
|
|
(
|
|
"fac_prvdr_oscar_num",
|
|
"str | None",
|
|
"CMS Certification Number (CCN) for institutional claims",
|
|
),
|
|
(
|
|
"qem_allowed_primary_ay1",
|
|
"float",
|
|
"Primary care allowed charge alignment year 1",
|
|
),
|
|
(
|
|
"qem_allowed_nonprimary_ay1",
|
|
"float",
|
|
"Non-primary care allowed charge alignment year 1",
|
|
),
|
|
(
|
|
"qem_allowed_other_ay1",
|
|
"float",
|
|
"Other specialist allowed charge alignment year 1",
|
|
),
|
|
(
|
|
"qem_allowed_primary_ay2",
|
|
"float",
|
|
"Primary care allowed charge alignment year 2",
|
|
),
|
|
(
|
|
"qem_allowed_nonprimary_ay2",
|
|
"float",
|
|
"Non-primary care allowed charge alignment year 2",
|
|
),
|
|
(
|
|
"qem_allowed_other_ay2",
|
|
"float",
|
|
"Other specialist allowed charge alignment year 2",
|
|
),
|
|
],
|
|
},
|
|
"prospective_plus_opportunity": {
|
|
"class_name": "ReachProspectivePlusOpportunity",
|
|
"description": "County-level eligible FFS beneficiary counts for voluntary alignment",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO identifier"),
|
|
("aco_type", "str", "High Needs, New Entrant, or Standard"),
|
|
("cnty_name", "str", "County name"),
|
|
("state_cd", "str", "State code"),
|
|
("fips_code", "str", "FIPS county code"),
|
|
("clnd_mnth", "int", "Calendar month"),
|
|
("eligible_benes", "int", "Total eligible FFS beneficiaries"),
|
|
],
|
|
},
|
|
"voluntary_alignment_response": {
|
|
"class_name": "ReachVoluntaryAlignmentResponse",
|
|
"description": "Outcome of paper-based voluntary alignment attestations",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO's identification number"),
|
|
(
|
|
"valid_flag",
|
|
"str",
|
|
"Yes/No - Indicator for whether record was valid",
|
|
),
|
|
(
|
|
"algn_flag",
|
|
"str",
|
|
"Indicator for whether record was reflected in alignment",
|
|
),
|
|
(
|
|
"response_code_list",
|
|
"str",
|
|
"Response codes: A0/A1/A2/V0/V1/V2/P0/P1/P2/E0/E1/E2/E3/E4/E5",
|
|
),
|
|
(
|
|
"id_received",
|
|
"str",
|
|
"Beneficiary Identifier received on SVA Attestation",
|
|
),
|
|
("bene_mbi", "str", "Beneficiary Identifier"),
|
|
("bene_first_name", "str", "Beneficiary's first name"),
|
|
("bene_last_name", "str", "Beneficiary's last name"),
|
|
("bene_line_1_address", "str", "First line of street address"),
|
|
("bene_line_2_address", "str | None", "Second line of street address"),
|
|
("bene_city", "str", "City name"),
|
|
(
|
|
"bene_state",
|
|
"str",
|
|
"Beneficiary's place of residence (state)",
|
|
),
|
|
("bene_zipcode", "str", "5-digit USPS zip code"),
|
|
(
|
|
"provider_name",
|
|
"str",
|
|
"Practice, clinic, physician or practitioner name",
|
|
),
|
|
(
|
|
"practitioner_name",
|
|
"str",
|
|
"Individual practitioner name or associated provider",
|
|
),
|
|
("ind_npi", "str", "NPI of attesting individual practitioner"),
|
|
("ind_tin", "str", "TIN of attesting individual practitioner"),
|
|
(
|
|
"signature_date",
|
|
"str",
|
|
"Date beneficiary signed form (MM/DD/YYYY)",
|
|
),
|
|
],
|
|
},
|
|
}
|
|
|
|
# ============================================================================
|
|
# FINANCE TABLES
|
|
# ============================================================================
|
|
|
|
FINANCE_TABLES = {
|
|
"risk_score_report": {
|
|
"class_name": "ReachRiskScoreReport",
|
|
"description": "Beneficiary-level monthly risk scores",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("aco_type", "str", "High Needs, New Entrant, or Standard"),
|
|
("clndr_yr", "str", "Calendar Year"),
|
|
("clndr_mo", "str", "Calendar Month (01=Jan, 02=Feb, etc.)"),
|
|
("bene_mbi", "str", "Beneficiary MBI"),
|
|
("bnmrk", "str", "Benchmark (A=AD, E=ESRD)"),
|
|
("raw_risk_score", "float", "Raw Risk Score for calendar month"),
|
|
(
|
|
"norm_risk_score",
|
|
"float",
|
|
"Normalized risk score for calendar month",
|
|
),
|
|
],
|
|
},
|
|
"qbr_report_parameters": {
|
|
"class_name": "ReachQbrReportParameters",
|
|
"description": "QBR - Basic parameters used to construct report",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("parameter_name", "str", "Parameter name"),
|
|
("parameter_value", "str", "Parameter value"),
|
|
("description", "str | None", "Parameter description"),
|
|
],
|
|
},
|
|
"qbr_financial_settlement": {
|
|
"class_name": "ReachQbrFinancialSettlement",
|
|
"description": "QBR - Shared Savings/Losses Settlement Calculation",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("report_period", "str", "Reporting period"),
|
|
("metric_name", "str", "Metric name"),
|
|
("metric_value", "float", "Metric value"),
|
|
("description", "str | None", "Metric description"),
|
|
],
|
|
},
|
|
"qbr_benchmark_historical": {
|
|
"class_name": "ReachQbrBenchmarkHistorical",
|
|
"description": "QBR - Calculation of Historical Blended Benchmark",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("benchmark_type", "str", "AD or ESRD"),
|
|
("calculation_component", "str", "Component name"),
|
|
("value", "float", "Component value"),
|
|
],
|
|
},
|
|
"qbr_risk_score": {
|
|
"class_name": "ReachQbrRiskScore",
|
|
"description": "QBR - Population-level PY Benchmark Risk Score",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("benchmark_type", "str", "AD or ESRD"),
|
|
("risk_score_component", "str", "Component name"),
|
|
("value", "float", "Component value"),
|
|
],
|
|
},
|
|
"qbr_stop_loss": {
|
|
"class_name": "ReachQbrStopLoss",
|
|
"description": "QBR - Stop-Loss Charge/Payout calculation (electing ACOs only)",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("calculation_type", "str", "Charge or Payout"),
|
|
("metric_name", "str", "Metric name"),
|
|
("metric_value", "float", "Metric value"),
|
|
],
|
|
},
|
|
"qbr_data_claims": {
|
|
"class_name": "ReachQbrDataClaims",
|
|
"description": "QBR - Aggregate claims data by claim type, benchmark type, alignment type, provider type",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("claim_type", "str", "Claim type category"),
|
|
("benchmark_type", "str", "AD or ESRD"),
|
|
("alignment_type", "str", "Alignment category"),
|
|
("provider_type", "str", "Provider category"),
|
|
("expenditure", "float", "Total expenditure"),
|
|
("count", "int", "Claim count"),
|
|
],
|
|
},
|
|
"apa_report_parameters": {
|
|
"class_name": "ReachApaReportParameters",
|
|
"description": "APA - Alternative Payment Arrangement Elections and lookback periods",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("parameter_name", "str", "Parameter name"),
|
|
("parameter_value", "str", "Parameter value"),
|
|
],
|
|
},
|
|
"apa_payment_history": {
|
|
"class_name": "ReachApaPaymentHistory",
|
|
"description": "APA - Non-claims-based payments received through last quarter",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("payment_period", "str", "Payment period"),
|
|
("payment_type", "str", "TCC/PCC/APO"),
|
|
("payment_amount", "float", "Payment amount"),
|
|
],
|
|
},
|
|
"apa_tcc_payment": {
|
|
"class_name": "ReachApaTccPayment",
|
|
"description": "APA - TCC Withhold Percentage calculation (TCC ACOs)",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("calculation_period", "str", "Calculation period"),
|
|
("component_name", "str", "Component name"),
|
|
("component_value", "float", "Component value"),
|
|
],
|
|
},
|
|
"apa_pcc_payment": {
|
|
"class_name": "ReachApaPccPayment",
|
|
"description": "APA - Base/Enhanced PCC per-beneficiary per-month calculation (PCC ACOs)",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("calculation_period", "str", "Calculation period"),
|
|
("pcc_type", "str", "Base or Enhanced"),
|
|
("component_name", "str", "Component name"),
|
|
("component_value", "float", "Component value"),
|
|
],
|
|
},
|
|
"apa_apo_payment": {
|
|
"class_name": "ReachApaApoPayment",
|
|
"description": "APA - APO per-beneficiary per-month calculation (PCC ACOs with APO)",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("calculation_period", "str", "Calculation period"),
|
|
("component_name", "str", "Component name"),
|
|
("component_value", "float", "Component value"),
|
|
],
|
|
},
|
|
"mer_claim_type": {
|
|
"class_name": "ReachMerClaimType",
|
|
"description": "MER - Monthly aggregations of incurred FFS expenditures by claim type and beneficiary counts",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("incurred_month", "str", "Incurred month (YYYYMM)"),
|
|
("claim_type", "str", "Claim type category"),
|
|
("expenditure", "float", "Total expenditure"),
|
|
("beneficiary_count", "int", "Beneficiary count"),
|
|
],
|
|
},
|
|
"mer_claim_lag": {
|
|
"class_name": "ReachMerClaimLag",
|
|
"description": "MER - Monthly aggregation by incurred and paid month",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("incurred_month", "str", "Incurred month (YYYYMM)"),
|
|
("paid_month", "str", "Paid month (YYYYMM)"),
|
|
("expenditure", "float", "Total expenditure"),
|
|
],
|
|
},
|
|
}
|
|
|
|
# ============================================================================
|
|
# QUALITY TABLES
|
|
# ============================================================================
|
|
|
|
QUALITY_TABLES = {
|
|
"quarterly_quality_report": {
|
|
"class_name": "ReachQuarterlyQualityReport",
|
|
"description": "QQR - Quarterly claims-based quality measure performance",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("report_quarter", "str", "Report quarter (YYYY-Q#)"),
|
|
(
|
|
"measure",
|
|
"str",
|
|
"ACR/UAMCC/DAH/TFU - Quality measure code",
|
|
),
|
|
("measure_name", "str", "Full measure name"),
|
|
("aco_score", "float", "ACO's performance score"),
|
|
("mean_score", "float", "Mean score for ACO cohort"),
|
|
("percentile_rank", "float | None", "Percentile ranking"),
|
|
(
|
|
"highest_benchmark",
|
|
"str | None",
|
|
"Highest benchmark threshold reached",
|
|
),
|
|
],
|
|
},
|
|
"annual_quality_summary": {
|
|
"class_name": "ReachAnnualQualitySummary",
|
|
"description": "AQR - Annual quality measure summary with points earned",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("performance_year", "str", "Performance year"),
|
|
(
|
|
"measure",
|
|
"str",
|
|
"ACR/UAMCC/DAH/TFU/CAHPS - Quality measure code",
|
|
),
|
|
("measure_name", "str", "Full measure name"),
|
|
("aco_score", "float", "ACO's quality measure score"),
|
|
("points_earned", "float", "Points earned (0-10 per measure)"),
|
|
("points_possible", "float", "Maximum possible points"),
|
|
(
|
|
"initial_quality_score",
|
|
"float",
|
|
"Total points earned / total possible * 100",
|
|
),
|
|
(
|
|
"ci_sep_gateway_multiplier",
|
|
"float",
|
|
"1.0 if met CI/SEP, 0.5 if not",
|
|
),
|
|
(
|
|
"hedr_adjustment",
|
|
"float",
|
|
"Up to 10% addition based on data reporting",
|
|
),
|
|
("total_quality_score", "float", "Final quality score (0-100%)"),
|
|
(
|
|
"quality_withhold_earn_back",
|
|
"float",
|
|
"Amount of 2% withhold earned back (0-2%)",
|
|
),
|
|
(
|
|
"hpp_bonus",
|
|
"float | None",
|
|
"Additional funds from High Performers Pool",
|
|
),
|
|
],
|
|
},
|
|
"annual_quality_cahps": {
|
|
"class_name": "ReachAnnualQualityCahps",
|
|
"description": "AQR - CAHPS survey results by Summary Survey Measure",
|
|
"fields": [
|
|
("aco_id", "str", "REACH ACO Identifier"),
|
|
("performance_year", "str", "Performance year"),
|
|
("ssm", "str", "Summary Survey Measure name"),
|
|
(
|
|
"aco_score",
|
|
"float",
|
|
"Patient mix adjusted linear mean score",
|
|
),
|
|
(
|
|
"all_reach_acos_score",
|
|
"float",
|
|
"Mean score across all REACH ACOs",
|
|
),
|
|
(
|
|
"ssm_percentile_rank",
|
|
"float | None",
|
|
"Percentile ranking (Standard and New Entrant ACOs only)",
|
|
),
|
|
(
|
|
"highest_benchmark_met",
|
|
"str | None",
|
|
"Highest threshold value based on percentile rank",
|
|
),
|
|
(
|
|
"points_earned",
|
|
"float",
|
|
"Points based on highest percentile threshold met (up to 10)",
|
|
),
|
|
],
|
|
},
|
|
}
|
|
|
|
|
|
# ============================================================================
|
|
# CODE GENERATION FUNCTIONS
|
|
# ============================================================================
|
|
|
|
|
|
def generate_table_class(
|
|
class_name: str, description: str, fields: list[tuple], schema: str | None = None
|
|
) -> str:
|
|
"""Generate a single SQLTable class definition."""
|
|
lines = []
|
|
lines.append(f"class {class_name}(SQLTable):")
|
|
lines.append(f' """{description}."""')
|
|
lines.append("")
|
|
|
|
# Add schema if provided
|
|
if schema:
|
|
lines.append(f' schema__ = "{schema}"')
|
|
lines.append("")
|
|
|
|
# Add fields
|
|
for field_name, field_type, field_desc in fields:
|
|
lines.append(f" {field_name}: {field_type}")
|
|
lines.append(f' """{field_desc}"""')
|
|
lines.append("")
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
def generate_alignment_module(output_path: Path) -> None:
|
|
"""Generate src/aco/table/reach_alignment.py."""
|
|
lines = []
|
|
lines.append('"""ACO REACH Alignment Report table models.')
|
|
lines.append("")
|
|
lines.append(
|
|
"Generated from: dev/PY2023 ACO REACH Reporting and Data Sharing Overview_v20232203.pdf"
|
|
)
|
|
lines.append('"""')
|
|
lines.append("")
|
|
lines.append("from __future__ import annotations")
|
|
lines.append("")
|
|
lines.append("from datetime import date")
|
|
lines.append("")
|
|
lines.append("from aco.table import SQLTable")
|
|
lines.append("")
|
|
lines.append("")
|
|
|
|
for table_id, spec in ALIGNMENT_TABLES.items():
|
|
class_def = generate_table_class(
|
|
spec["class_name"],
|
|
spec["description"],
|
|
spec["fields"],
|
|
)
|
|
lines.append(class_def)
|
|
lines.append("")
|
|
|
|
output_path.write_text("\n".join(lines))
|
|
print(f"✓ Generated {output_path} ({len(ALIGNMENT_TABLES)} tables)")
|
|
|
|
|
|
def generate_finance_module(output_path: Path) -> None:
|
|
"""Generate src/aco/table/reach_finance.py."""
|
|
lines = []
|
|
lines.append('"""ACO REACH Finance Report table models.')
|
|
lines.append("")
|
|
lines.append(
|
|
"Generated from: dev/PY2023 ACO REACH Reporting and Data Sharing Overview_v20232203.pdf"
|
|
)
|
|
lines.append('"""')
|
|
lines.append("")
|
|
lines.append("from __future__ import annotations")
|
|
lines.append("")
|
|
lines.append("from aco.table import SQLTable")
|
|
lines.append("")
|
|
lines.append("")
|
|
|
|
for table_id, spec in FINANCE_TABLES.items():
|
|
class_def = generate_table_class(
|
|
spec["class_name"],
|
|
spec["description"],
|
|
spec["fields"],
|
|
)
|
|
lines.append(class_def)
|
|
lines.append("")
|
|
|
|
output_path.write_text("\n".join(lines))
|
|
print(f"✓ Generated {output_path} ({len(FINANCE_TABLES)} tables)")
|
|
|
|
|
|
def generate_quality_module(output_path: Path) -> None:
|
|
"""Generate src/aco/table/reach_quality.py."""
|
|
lines = []
|
|
lines.append('"""ACO REACH Quality Report table models.')
|
|
lines.append("")
|
|
lines.append(
|
|
"Generated from: dev/PY2023 ACO REACH Reporting and Data Sharing Overview_v20232203.pdf"
|
|
)
|
|
lines.append('"""')
|
|
lines.append("")
|
|
lines.append("from __future__ import annotations")
|
|
lines.append("")
|
|
lines.append("from aco.table import SQLTable")
|
|
lines.append("")
|
|
lines.append("")
|
|
|
|
for table_id, spec in QUALITY_TABLES.items():
|
|
class_def = generate_table_class(
|
|
spec["class_name"],
|
|
spec["description"],
|
|
spec["fields"],
|
|
)
|
|
lines.append(class_def)
|
|
lines.append("")
|
|
|
|
output_path.write_text("\n".join(lines))
|
|
print(f"✓ Generated {output_path} ({len(QUALITY_TABLES)} tables)")
|
|
|
|
|
|
def generate_filename_patterns(output_path: Path) -> None:
|
|
"""Generate src/aco/table/reach_filenames.py with rex-compatible filename classifiers."""
|
|
content = '''"""ACO REACH filename pattern recognition for rex integration.
|
|
|
|
Generated from: dev/PY2023 ACO REACH Reporting and Data Sharing Overview_v20232203.pdf
|
|
|
|
General Pattern: P.D****.FILECODE.Dyymmdd.Thhmmsst.[xlsx|csv|zip|txt]
|
|
|
|
Components:
|
|
- P: Prefix indicating ACO REACH file
|
|
- D****: Entity ID (4 digits)
|
|
- FILECODE: 5-character file code identifier
|
|
- Dyymmdd: Date (D + yy=year + mm=month + dd=day)
|
|
- Thhmmsst: Time (T + hh=hour + mm=minute + ss=second + t=millisecond)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from typing import TypedDict
|
|
|
|
|
|
class ReachFileInfo(TypedDict, total=False):
|
|
"""Parsed REACH filename information."""
|
|
|
|
file_type: str # PAER, ALGC, PALMR, etc.
|
|
entity_id: str # 4-digit entity ID
|
|
date: str # yymmdd
|
|
time: str # hhmmsst
|
|
report_period: str | None # Q1, Q2, Q3, Q4 for quarterly reports
|
|
version: str | None # Version suffix for quality reports
|
|
|
|
|
|
# File code mappings
|
|
FILE_CODES = {
|
|
# Alignment files
|
|
"PAER": "preliminary_alignment_estimate",
|
|
"ALGC": "beneficiary_alignment_report",
|
|
"PALMR": "provider_alignment_report",
|
|
"PPOPR": "prospective_plus_opportunity",
|
|
"PBVAR": "voluntary_alignment_response",
|
|
# Finance files
|
|
"PRLBR": "preliminary_benchmark_report",
|
|
"PRBRU": "preliminary_benchmark_report_unredacted",
|
|
"QBNMR": "quarterly_benchmark_report",
|
|
"ALPAR": "preliminary_alternative_payment",
|
|
"PLARU": "preliminary_alternative_payment_unredacted",
|
|
"ALTPR": "alternative_payment_arrangement",
|
|
"MEXPR": "monthly_expenditure_report",
|
|
"TPARC": "weekly_claims_reduction",
|
|
# Quality files
|
|
"QTLQR": "quarterly_quality_report",
|
|
"ANLQR": "annual_quality_report",
|
|
# Risk score and CCLFs
|
|
"RAP": "risk_score_report", # RAP*V* pattern
|
|
"ZCY": "monthly_cclf", # ZCY** pattern
|
|
"ZCR": "runout_cclf", # ZCR** pattern
|
|
}
|
|
|
|
|
|
# Regex patterns for each file type
|
|
REACH_FILE_PATTERN = re.compile(
|
|
r"P\\.D(?P<entity_id>\\d{4})\\.(?P<file_code>[A-Z]{5,6}\\d*)"
|
|
r"\\.D(?P<date>\\d{6})\\.T(?P<time>\\d{7})"
|
|
r"(?P<version>[0-9a-z])?\\.(?P<extension>xlsx|csv|zip|txt)"
|
|
)
|
|
|
|
# Special patterns for quarterly reports (e.g., PPOPR.Q1)
|
|
QUARTERLY_PATTERN = re.compile(
|
|
r"P\\.D(?P<entity_id>\\d{4})\\.(?P<file_code>[A-Z]{5,6})\\.Q(?P<quarter>[1-4])"
|
|
r"\\.D(?P<date>\\d{6})\\.T(?P<time>\\d{7})"
|
|
r"(?P<version>[0-9a-z])?\\.(?P<extension>xlsx|csv|zip|txt)"
|
|
)
|
|
|
|
# Quality report patterns (special time format: Tmmddyyr)
|
|
QUALITY_PATTERN = re.compile(
|
|
r"P\\.D(?P<entity_id>\\d{4})\\.(?P<file_code>QTLQR|ANLQR)"
|
|
r"(?:\\.Q(?P<quarter>[1-4]))?"
|
|
r"\\.D(?P<date>\\d{6})\\.T(?P<time>\\d{6})"
|
|
r"(?P<version>[0-9])?\\.(?P<extension>xlsx)"
|
|
)
|
|
|
|
# CCLF patterns (e.g., P.A****.ACO.ZCY**.Dyymmdd.Thhmmsst.zip)
|
|
CCLF_PATTERN = re.compile(
|
|
r"P\\.A(?P<entity_id>\\d{4})\\.ACO\\.(?P<file_code>ZC[YR])(?P<year>\\d{2})"
|
|
r"\\.D(?P<date>\\d{6})\\.T(?P<time>\\d{7})\\.zip"
|
|
)
|
|
|
|
# Risk Score Report patterns (e.g., P.D****.RAP*V*.Dyymmdd.Thhmmsst.zip)
|
|
RSR_PATTERN = re.compile(
|
|
r"P\\.D(?P<entity_id>\\d{4})\\.RAP(?P<py>\\d)V(?P<version>\\d)"
|
|
r"\\.D(?P<date>\\d{6})\\.T(?P<time>\\d{7})\\.zip"
|
|
)
|
|
|
|
|
|
def classify(filename: str) -> ReachFileInfo | None:
|
|
"""Classify a REACH filename and extract metadata.
|
|
|
|
Args:
|
|
filename: REACH filename to parse
|
|
|
|
Returns:
|
|
ReachFileInfo dict with parsed metadata, or None if not a valid REACH file
|
|
|
|
Examples:
|
|
>>> classify("P.D1234.PAER.D230101.T120000.xlsx")
|
|
{'file_type': 'preliminary_alignment_estimate', 'entity_id': '1234', ...}
|
|
|
|
>>> classify("P.D1234.PPOPR.Q1.D230101.T120000.xlsx")
|
|
{'file_type': 'prospective_plus_opportunity', 'entity_id': '1234',
|
|
'report_period': 'Q1', ...}
|
|
|
|
>>> classify("P.A1234.ACO.ZCY23.D230101.T1200000.zip")
|
|
{'file_type': 'monthly_cclf', 'entity_id': '1234', 'year': '23', ...}
|
|
"""
|
|
# Try quality report pattern first (special time format)
|
|
match = QUALITY_PATTERN.match(filename)
|
|
if match:
|
|
data = match.groupdict()
|
|
file_code = data["file_code"]
|
|
result: ReachFileInfo = {
|
|
"file_type": FILE_CODES.get(file_code, file_code.lower()),
|
|
"entity_id": data["entity_id"],
|
|
"date": data["date"],
|
|
"time": data["time"],
|
|
}
|
|
if data.get("quarter"):
|
|
result["report_period"] = f"Q{data['quarter']}"
|
|
if data.get("version"):
|
|
result["version"] = data["version"]
|
|
return result
|
|
|
|
# Try quarterly pattern
|
|
match = QUARTERLY_PATTERN.match(filename)
|
|
if match:
|
|
data = match.groupdict()
|
|
file_code = data["file_code"]
|
|
result = {
|
|
"file_type": FILE_CODES.get(file_code, file_code.lower()),
|
|
"entity_id": data["entity_id"],
|
|
"date": data["date"],
|
|
"time": data["time"],
|
|
"report_period": f"Q{data['quarter']}",
|
|
}
|
|
if data.get("version"):
|
|
result["version"] = data["version"]
|
|
return result
|
|
|
|
# Try CCLF pattern
|
|
match = CCLF_PATTERN.match(filename)
|
|
if match:
|
|
data = match.groupdict()
|
|
file_code = data["file_code"]
|
|
return {
|
|
"file_type": FILE_CODES.get(file_code, file_code.lower()),
|
|
"entity_id": data["entity_id"],
|
|
"date": data["date"],
|
|
"time": data["time"],
|
|
"year": data["year"],
|
|
}
|
|
|
|
# Try Risk Score Report pattern
|
|
match = RSR_PATTERN.match(filename)
|
|
if match:
|
|
data = match.groupdict()
|
|
return {
|
|
"file_type": "risk_score_report",
|
|
"entity_id": data["entity_id"],
|
|
"date": data["date"],
|
|
"time": data["time"],
|
|
"version": f"PY{data['py']}_V{data['version']}",
|
|
}
|
|
|
|
# Try standard pattern
|
|
match = REACH_FILE_PATTERN.match(filename)
|
|
if match:
|
|
data = match.groupdict()
|
|
file_code_raw = data["file_code"]
|
|
# Handle codes with trailing digits (e.g., ALGC01, ALGC02)
|
|
file_code_base = file_code_raw[:5] if len(file_code_raw) >= 5 else file_code_raw
|
|
result = {
|
|
"file_type": FILE_CODES.get(file_code_base, file_code_base.lower()),
|
|
"entity_id": data["entity_id"],
|
|
"date": data["date"],
|
|
"time": data["time"],
|
|
}
|
|
if data.get("version"):
|
|
result["version"] = data["version"]
|
|
return result
|
|
|
|
return None
|
|
'''
|
|
|
|
output_path.write_text(content)
|
|
print(f"✓ Generated {output_path} (filename pattern classifier)")
|
|
|
|
|
|
def main():
|
|
"""Generate all ACO REACH table models and filename patterns."""
|
|
project_root = Path(__file__).resolve().parents[2]
|
|
table_dir = project_root / "src" / "aco" / "table"
|
|
table_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
print("Generating ACO REACH table models...")
|
|
print("=" * 60)
|
|
|
|
# Generate alignment tables
|
|
alignment_path = table_dir / "reach_alignment.py"
|
|
generate_alignment_module(alignment_path)
|
|
|
|
# Generate finance tables
|
|
finance_path = table_dir / "reach_finance.py"
|
|
generate_finance_module(finance_path)
|
|
|
|
# Generate quality tables
|
|
quality_path = table_dir / "reach_quality.py"
|
|
generate_quality_module(quality_path)
|
|
|
|
# Generate filename patterns
|
|
filename_path = table_dir / "reach_filenames.py"
|
|
generate_filename_patterns(filename_path)
|
|
|
|
print("=" * 60)
|
|
print(
|
|
f"Total tables generated: {len(ALIGNMENT_TABLES) + len(FINANCE_TABLES) + len(QUALITY_TABLES)}"
|
|
)
|
|
print(f" Alignment: {len(ALIGNMENT_TABLES)}")
|
|
print(f" Finance: {len(FINANCE_TABLES)}")
|
|
print(f" Quality: {len(QUALITY_TABLES)}")
|
|
print("✓ All ACO REACH models generated successfully")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|