v2.25.3 — audit 2026-06-20 follow-up batch 3 (Low-severity sweep)
Third and final follow-up batch to the 2026-06-20 codebase audit — the actionable Low-severity findings. Test-first for every behaviour change. No API, schema, or dependency changes. Clears the remaining actionable audit items (Criticals/Highs/Mediums shipped in v2.25.1 / v2.25.2).
Fixed
- Stats source breakdown never renders a negative "other" slice — the
adsb/mlatpercentages are each rounded independently in SQL, so their sum can exceed 100 (e.g. 6.3% + 93.8%); the remainder is now floored at 0 (windowed + lifetime). - API error toasts surface the server's reason —
ApiErrorparses a FastAPI{"detail": …}body and includes it after theHTTP <status>prefix (and as.detail), so a rejected request shows why. import_rrdno longer mislabels atotal-only interval (RRDpositionsDS absent) as aircraft-with-position — it gaps instead of over-reporting coverage.db_updaterlogs/returns the distinct rows actually inserted (INSERT OR IGNOREdedup), not the parsed-row count.migrate_v6rejects a non-existent database path up front (exit 1) instead of creating a stray empty file and failing later with an opaque "no such table".purge_mlat_gs_spikesfloorsmin_readingsto 2 insidescan_statistical_outliers(not only the CLI), so a non-CLI caller can't crash the quantile computation on a single-reading flight.- VDL2 normalize drops a glitchy non-positive
freqto NULL instead of converting e.g.-1 MHz.
Cleanups
Dead purge_bad_gs branch removed; notifier photo-path debug logs routed through _describe_exc; BATCH_SIZE import hoisted; stale health.py comments reworded; clarity comments on collector._open_flight + useMapPlaybackState.onSeek. No behaviour change.
Tests
New coverage for the cache prewarm-schedule ordering, cleaners non-finite string rejection, the VDL2 decoder= override + negative-freq drop, import_rrd.main, the db_updater duplicate-ICAO contract, and frontend AcarsPanel / AboutReceiverFooter / TopChartMultiples / MetricCell / MapModeControl (incl. the deselect null-guard) / useMapPlaybackState / watchlist optimistic-delete rollback / apiFetch detail + header-merge. Every bug-fix test verified fail-first. Suite: backend 2195 passed / 2 skipped, frontend 529 passed.
Full changelog: v2.25.2...v2.25.3