- Fix score_pressure crash on nil pressure_mb (coastal HRRR points)
- Set 10-min timeout on grid score upsert transaction (was :infinity)
- Single DELETE for prune_old_scores instead of N queries in a loop
- Remove dead load_hrrr_refractivity that loaded 95k rows into nil map
- Pass selected_time to point_detail to skip latest_valid_time sub-query
- Batch station existence checks (1 query per path point, not per station)
- Batch solar index upserts via insert_all in chunks of 500
- Batch backfill_distances via single UPDATE FROM VALUES statement
- Add is_grid_point boolean + partial index to hrrr_profiles (replaces
non-sargable modular arithmetic filter on every weather map query)
- Add partial index on contacts(qso_timestamp) WHERE pos1 IS NOT NULL
- Move backfill enqueue to Oban worker so UI returns immediately
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.
- Database triggers on contacts and oban_jobs fire pg_notify on
status/state changes
- RepoListener GenServer subscribes via Postgrex.Notifications and
broadcasts to PubSub
- Backfill dashboard subscribes to PubSub instead of 2-second polling
- Eliminates periodic SELECT queries, updates arrive instantly
- Unified queue_info helper shows "(N jobs in queue)" on all spinners
- Solar index auto-enqueues when missing on contact page
- Freshness monitor disabled in dev
- Fix test stubs for solar client
- SolarIndexWorker accepts date arg for specific date fetch
- Contact show page enqueues solar fetch when data missing
- PubSub broadcast on solar data arrival, live-updates page
- Spinner shown while fetching
- Migration renames table, column, all indexes, and FK constraints
- Contact schema now references "contacts" table
- TerrainProfile foreign key renamed from qso_id to contact_id
- All code and tests updated to use contact_id
Previously, if a job was cancelled or lost while status was :queued,
viewing the contact detail page would not re-enqueue. Now HRRR,
weather/soundings, and terrain all re-enqueue when :queued with no
data, relying on Oban uniqueness for deduplication.
The 6 sequential count(*) queries on large tables were timing out
at 15s when concurrent HRRR batch inserts held locks. Reuse the
n_live_tup estimates already fetched from pg_stat_user_tables.
Shows provenance of all data used in the analysis:
- HRRR: path profile count, pressure levels, valid time, grid point
- Elevation: sample count, path distance, source (SRTM), duct layers
- Terrain: sample count, verdict, max elevation, diffraction loss
- Surface observations: station count and time range
- Soundings: profile count, stations, levels, ducting detection
- Solar indices: SFI, SSN, Ap
- Enrichment status breakdown per type (HRRR/Weather/Terrain/IEMRE)
with color-coded status counts (complete/pending/queued/failed)
- Database overview: total DB size, HRRR profiles, observations,
soundings with per-contact averages
- Table sizes: rows and disk size per table, sorted by size
- All stats auto-refresh every 2 seconds
Collapsible control panel with hamburger toggle, detail panel as
bottom sheet, compact legend moved to top-right, and scaled timeline
buttons for narrow viewports.
- Radio.ensure_positions!/1 computes pos1/pos2/distance from grids
- Called in contact show page mount and enqueue_for_contact
- Migration backfills positions for existing contacts missing them
- Migration corrects enrichment statuses based on actual data presence
- Backfill dashboard includes contacts with grids but no positions
- New fields: hrrr_status, weather_status, terrain_status, iemre_status
with values: pending, queued, processing, complete, failed, unavailable
- EnrichmentStatus module defines valid state transitions
- Migration backfills: queued=true → complete, false → pending
- Workers set status on transitions (queued on enqueue, complete on finish)
- Show page reads status from contact struct, not computed dynamically
- Backfill dashboard queries status fields for accurate progress counts
- Remove cron-scheduled ContactWeatherEnqueueWorker (enrichment only on
submission, page view, or manual backfill)
- Partial indexes on status != 'complete' for fast unprocessed lookups