fix(config-sync): store ALTITUDE as bare metres end-to-end#103
Merged
Conversation
Centralizes altitude conversion across configure.sh, apl-feed apply, apl-feed config sync, and the on-disk migrator. Operator inputs stay suffix-tolerant (120 / 120m / 400ft / 42.5); the helper converts to bare metres and range-gates post-conversion against [-1000, 10000], matching the website's alt validator (20000ft is newly accepted; 33000ft is newly rejected). valid_altitude empty-as-tombstone enables the inbound alt.value: null round-trip. Retires normalize_altitude. The fixture file is shared with image-webconfig's Go/JS mirrors for byte-exact parity.
Routes _apl_feed_apply_canonicalize_altitude through altitude_to_bare_metres so feed.env carries the same bare-metres representation the wire format expects. Sharpens the validator error message to mention the metres range. Adds coverage for empty-as-tombstone, 400ft -> 121.92, 20000ft acceptance, and 33000ft rejection.
…w helper configure.sh's non-interactive and interactive paths feed.env via tee, bypassing the apply layer — so a fresh image install was still writing suffixed values to disk. Switching it to altitude_to_bare_metres aligns with the new canonical form before any operator-triggered apply runs. apl-feed mlat geo/setup hand raw operator input to apl_feed_apply, which canonicalizes on write; the local preview block uses the helper to show what will land on disk.
…date Already-flashed feeders carry suffixed ALTITUDE on disk; running feed/update.sh now flips them to the new canonical form during run_config_file_migrations. The migrator is idempotent, preserves all non-altitude keys, leaves unparseable values alone with a stderr warning, and intentionally does not bump feed.meta.json so a freshly-stamped website edit still beats the pre-migration feeder tuple.
The website serializer (accounts/serializers/feeder.py) requires alt.value to be a number or null; sending the unit-suffixed string was the actual rejection cause behind "alt.value must be a number or null". Outbound now runs the on-disk value through altitude_to_bare_metres so even pre-migration suffixed disks emit a clean number on the wire. Unparseable / out-of-range disk values omit .fields.alt entirely (instead of sending a null tombstone alongside a fresh feeder edited_at) so a corrupted local copy never wipes the website's last-known-good value. Also fixes the inbound translation path's TAB-separator collapse on null tombstones — bash read treats TAB as whitespace and merged adjacent fields, so an alt.value:null response would warn reason=bad_edited_by and skip apply. Switched to ASCII US (0x1F) which read treats as a single delimiter.
Audit pass across the remaining bats files that still pinned ALTITUDE="<n>m" on disk or in journald output. apl-feed apply now canonicalizes to bare metres so the assertions move with the on-disk shape; tests that used suffixed seeds as inert input still work but the seeds are normalized for clarity.
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.
The website's config-sync wire format expects
alt.valueas a JSON number in metres, but the on-disk format until now carried a unit-suffixed string (120m,400ft). Every outbound sync was getting rejected at the website withalt.value must be a number or null. A symmetric round-trip also silently flipped an operator'sftchoice to metres on the first successful sync.This change centralizes altitude conversion in one helper (
altitude_to_bare_metres) and routes every write path through it:apl-feed apply,configure.sh,apl-feed mlat, the outbound config-sync payload builder, and a newmigrate_altitude_to_bare_metresthat rewrites already-flashed feeders on the nextfeed/update.sh. Operator input stays suffix-tolerant; the canonical disk form is bare metres. Range gating moves to post-conversion metres so20000ft(~6096m) is now accepted and33000ft(~10058m) is now rejected, matching the website's validator. A shared fixture file pins byte-exact outputs so the Go and JS mirrors in image-webconfig stay in lockstep.Addresses #101