fix: snap weather-proxy coordinates before they leave the device - #129
Merged
Conversation
AviationWeatherService sent full double-precision live GPS position in the metar/sigmet query strings, on a timer for as long as a briefing stayed open. A query string is the least-protected place a coordinate can sit: it persists in edge request logs long after the response itself is gone. The weather worker already snaps every incoming lat/lon to a 0.25 degree grid (GRID_DEGREES) before it builds a cache key, an upstream URL, or a distance sort, so the extra precision bought nothing. Responses are unchanged. This applies the same grid client-side, matching what WindsAloftService has always done. Adds AviationWeatherServiceTests: the grid (quantization, both hemispheres, idempotence against the worker's second snap, parity with WindsAloftService, half-cell displacement bound) and the decode contract against the proxy's response shape, which mirrors types living in a separate repository that nothing in the build would catch drifting. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fetzu
force-pushed
the
fix/weather-coordinate-snapping
branch
from
August 15, 2026 11:51
83290fd to
523964d
Compare
| let lon = Self.snap(coordinate.longitude) | ||
| guard let url = URL(string: | ||
| "\(baseURL)/v1/metar?lat=\(coordinate.latitude)&lon=\(coordinate.longitude)&radius=60" | ||
| "\(baseURL)/v1/metar?lat=\(lat)&lon=\(lon)&radius=60" |
| let lon = Self.snap(coordinate.longitude) | ||
| guard let url = URL(string: | ||
| "\(baseURL)/v1/sigmet?lat=\(coordinate.latitude)&lon=\(coordinate.longitude)&radius=150" | ||
| "\(baseURL)/v1/sigmet?lat=\(lat)&lon=\(lon)&radius=150" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
AviationWeatherServicesent full double-precision live GPS position in the METAR and SIGMET query strings, on a timer for as long as a briefing stayed open. This snaps to the same 0.25° grid the siblingWindsAloftServicehas always used, and adds the service's first test class.Why
A query string is the least-protected place a coordinate can sit — it persists in edge request logs long after the response is gone, and this one is derived from a live flight track.
The extra precision bought nothing. The weather worker's
parseCoordinates→snapToGrid(GRID_DEGREES = 0.25inworkers/weather/src/lib.ts) already rounds every incoming lat/lon to this grid before it builds a cache key, an upstream URL, or the distance sort intransformMetars/filterSigmets. Responses are byte-identical. A half-cell is ~7.5 nm of latitude, an order of magnitude inside the 60 nm METAR radius and two inside the 150 nm SIGMET radius.How
gridDegrees+snap(_:)added toAviationWeatherService, bothnonisolated, mirroringWindsAloftService.fetchMetarsandfetchSigmetssnap before interpolating into the URL.AviationWeatherServiceTests(12 tests):WindsAloftService.snap, half-cell displacement bound, and precision-discard on a real full-precision fix.workers/weather/src/aviation.ts. These types mirror a separate repository and nothing in the build catches a rename. Includes the VRB-vs-absent-wind distinction the service's doc comment calls out, and both timestamp forms the worker emits (isoTimereturnstoISOString()with milliseconds for epoch inputs, a passthrough string without them otherwise).Test
scripts/run-tests.sh— 504 tests, 0 failures on iPad Air 11-inch (M4). New class alone: 12 tests, 0 failures.🤖 Generated with Claude Code