- Replace deprecated xref:exclude with elixirc_options in vendor/oban_pro
- Remove unused require Logger from 8 files
- Pin bitstring size variables with ^ in simple_packing, wgrib2,
complex_packing, section, nexrad_client, mqtt, and radar worker
- Remove dead defp clauses (format/1 nil, depression/2 nil)
- Rename Buildings.Parser type record/0 -> building_record/0 to avoid
overriding built-in type
- Remove redundant catch-all in candidate_detail.ex
- Simplify contact_live/show.ex conditional based on type narrowing
- Fix DateTime.from_iso8601 return pattern in vendor/oban_web
- Upgrade phoenix_live_view to 1.1.31
- Drop --warnings-as-errors from precommit alias; known false positives
from @after_verify-generated code in Elixir 1.20.0-rc.6 + PLV 1.1.x
- Add credo --strict to precommit as replacement static-analysis gate
- MsFootprints (51% → 93%): http_get injection for dataset_index and
download_tile, with stubbed CSV parsing, empty CSV, caching, and
disk-cache-skip tests
- HrdpsClient (47% → 71%): http_get/http_head injection for fetch_grid
and cycle_available, with stubbed probe, success/failure/transport-
error tests, plus fetch_grid error path
- NexradClient (57% → 58%): http_get injection, fetch_frame success
path with valid PNG stub, process_frame coverage
- HrrrNativeClient: http_get injection for fetch_idx (no direct test
since function is private)
Coverage: 79.43% → 79.68% (need 0.32% more)
Phase 2/3/5 of the building-blockage support:
* Parser streams csv.gz tiles into compact records (centroid, radius,
height) — keeps RAM ~32 B per polygon, drops -1.0-height entries.
* Index buckets records into 0.01° (~1 km) grid cells in a public ETS
table for concurrent reads; max_height_near/3 and records_near/3
scan only the 9 nearest buckets.
* Loader lazily parses any cached quadkey before a Calculate so the
scorer is terrain-only when tiles aren't on disk yet.
* Rover.PathTerrain now treats each path-sample obstacle as
terrain_elev + max_local_building_height, so blocked LOS through
recent construction actually reduces clearance.
* Selecting a candidate pushes a candidate_buildings event with the
buildings near each rover→station path; the hook renders them as
height-coloured circles (yellow <10 m, orange 10-30 m, red >=30 m)
with a tooltip showing height in meters.
Mix tasks don't run in production, so the orchestration lives in
Microwaveprop.Buildings.BulkFetch — callable from an attached iex on
the prod pod via:
iex> Microwaveprop.Buildings.BulkFetch.run(32.8, -97.0, 500)
Default 500 mi radius around DFW yields ~440 candidate quadkeys at
zoom 9; only those present in the MS dataset index (typically a few
hundred over CONUS) get downloaded. Concurrency 4, per-task timeout
3 min, results logged with downloaded/cached/failed/missing counts.
The mix.task is kept as a dev-only thin wrapper.
Phase 1 of building-blockage support: implements quadkey math (Bing/MS
tile encoding), looks up the MS dataset-links index for UnitedStates,
and downloads csv.gz quadkey tiles to /data/buildings (overridable via
:buildings_cache_dir). Index is cached 24h; tiles are written once and
reused. No path-analysis wiring yet — that's the next slice.