Files
CA/backend/utils/date_helpers.py
Akiba So e64ca3b4f5 fix: analysis 500s, caching, alert page perf
P0: Fix KeyError in 3 analysis endpoints. geojson.py stores 1d risk
as "risk_value" but analysis.py accessed "risk_1d" — always crashed.

Backend: Add lru_cache to GeoJSON/CSV/Parquet loaders, date helpers,
and district loader. Add try/except and FileNotFoundError guards.

Frontend: Debounce riskRange, merge counts into useMemo, stabilize
handleGridClick with ref, memoize nearest-grid scan, wrap AlertMap
in React.memo, switch useLodGrid from fetch to cachedGet.
2026-06-05 02:27:10 +08:00

54 lines
1.4 KiB
Python

"""
Date utilities: finding latest dates from GeoJSON files, parsing date strings.
"""
import glob
import re
from functools import lru_cache
from pathlib import Path
from fastapi import HTTPException
from config import DATA_DIR, DATE_FORMAT_GEOJSON
@lru_cache(maxsize=1)
def get_latest_date() -> str:
"""Get latest available date from GeoJSON files in DATA_DIR."""
pattern = str(DATA_DIR / "risk_*.geojson")
files = glob.glob(pattern)
if not files:
raise HTTPException(status_code=500, detail="No risk data files found")
dates = []
for f in files:
match = re.search(r"risk_(\d{8})\.geojson", f)
if match:
dates.append(match.group(1))
if not dates:
raise HTTPException(status_code=500, detail="No valid risk data files found")
return max(dates)
@lru_cache(maxsize=1)
def get_available_dates(days: int = 30) -> list[str]:
"""Get list of available dates, most recent first."""
pattern = str(DATA_DIR / "risk_*.geojson")
files = glob.glob(pattern)
dates: list[str] = []
for f in files:
match = re.search(r"risk_(\d{8})\.geojson", f)
if match:
dates.append(match.group(1))
dates.sort(reverse=True)
return dates[:days]
def validate_date_format(date: str) -> bool:
"""Check if date string matches YYYYMMDD format."""
import re
return bool(re.compile(r"^\d{8}$").match(date))