fix: ZIP rep lookup — correct TIGERweb field names for 119th Congress

Actual API fields are STATE (not STATEFP) and CD119 (not CD119FP).
GEOID primary path works for regular districts; fallback now uses
STATE + CD\d+ pattern confirmed against live TIGERweb responses.

Authored by: Jack Levy
This commit is contained in:
Jack Levy
2026-03-15 10:58:50 -04:00
parent 4cada298ab
commit bb10ff6dac

View File

@@ -94,9 +94,8 @@ async def get_members_by_zip(zip_code: str, db: AsyncSession = Depends(get_db)):
continue
attrs = item.get("attributes", {})
# GEOID / GEOID20 — 2-char state FIPS + 2-char district (e.g. "0618" = CA-18)
# 119th Congress layers use GEOID20 (2020 Census vintage)
geoid = str(attrs.get("GEOID") or attrs.get("GEOID20") or "").strip()
# Primary: GEOID = 2-char state FIPS + 2-char district (e.g. "0630" = CA-30)
geoid = str(attrs.get("GEOID") or "").strip()
if len(geoid) == 4 and geoid.isdigit():
state_fips = geoid[:2]
district_fips = geoid[2:]
@@ -105,12 +104,12 @@ async def get_members_by_zip(zip_code: str, db: AsyncSession = Depends(get_db)):
if state_code:
break
# Fallback: explicit field names (e.g. CD119FP + STATEFP20)
cd_field = next((k for k in attrs if re.match(r"CD\d+FP$", k)), None)
state_field = next((k for k in attrs if "STATEFP" in k.upper()), None)
if cd_field and state_field:
# Fallback: STATE + CD{session} fields (e.g. STATE="06", CD119="30")
state_val = attrs.get("STATE")
cd_field = next((k for k in attrs if re.match(r"CD\d+$", k)), None)
if state_val and cd_field:
try:
state_fips = str(attrs[state_field]).zfill(2)
state_fips = str(state_val).zfill(2)
district_fips = str(attrs[cd_field]).zfill(2)
state_code = _FIPS_TO_STATE.get(state_fips)
district_num = str(int(district_fips)) if district_fips.strip("0") else None
@@ -119,11 +118,6 @@ async def get_members_by_zip(zip_code: str, db: AsyncSession = Depends(get_db)):
except (ValueError, TypeError):
pass
logger.debug(
"ZIP %s: could not parse layer %r — attrs: %s",
zip_code, item.get("layerName"), list(attrs.keys()),
)
if not state_code:
logger.warning(
"ZIP %s: no CD found. Layers: %s",