Removed n_live_tup > 0 filter that hid tables when pg_stats reports 0 rows
during VACUUM. Added dead tuple column with warning highlight to monitor
vacuum progress. Also includes Styler reformatting and unused dep cleanup.
- Only deduplicate against active jobs (available/scheduled/executing/
retryable), not completed ones. Completed jobs no longer block new
inserts for the same args.
- Period reduced from 3600s to 300s
- Fixes contacts stuck in :queued with no actual Oban jobs
WeatherFetchWorker, HrrrFetchWorker, and TerrainProfileWorker now have
unique: [period: 3600] — Oban deduplicates identical jobs within 1 hour.
Repeated page loads won't queue redundant fetches.
- HRRR and terrain workers broadcast via PubSub on completion
- Contact show page subscribes and recomputes elevation profile,
propagation analysis, and HRRR data on receipt
- Page updates in-place without reload when background jobs finish
QSO enrichment now groups all path points by HRRR hour and creates
one batch job per hour instead of one job per point. The batch job
downloads the GRIB2 data once and extracts all needed points from
the same binary. Legacy single-point jobs are still supported for
backward compatibility.
Instead of listing every permanent failure string, only retry on known
transient errors (5xx, 429, network exceptions). Everything else —
GRIB decode errors, 404s, range request failures, index out of range —
is cancelled immediately.
S3 returns 200 with the full ~116MB file instead of 206 for some older
HRRR data. Treat this as a permanent failure instead of trying to parse
the entire file.
HTTP 404 means the HRRR data doesn't exist on NOAA S3 (pre-2014
dates, etc.) and will never succeed. Return {:cancel, reason}
instead of {:error, reason} so Oban stops retrying immediately.
20 attempts with exponential backoff capped at 6 hours ensures
data is eventually fetched even during extended rate limiting or
API outages (~3 days of retrying before giving up).
HRRR provides hourly 3km-resolution atmospheric profiles, filling the
temporal gaps (12-hourly soundings) and spatial gaps (only 9 sounding
stations) in our current weather data.
- Add hrrr_profiles table and hrrr_queued flag on QSOs
- HrrrClient fetches GRIB2 data via HTTP Range requests + wgrib2
- HrrrFetchWorker derives refractivity/ducting params via SoundingParams
- QsoWeatherEnqueueWorker now also enqueues HRRR jobs
- QSO show page displays HRRR section with collapsible profile
- Dockerfile builds wgrib2 from source for production