Skip to content

fix(config-sync): store ALTITUDE as bare metres end-to-end#103

Merged
d4rken merged 6 commits into
devfrom
fix/altitude-bare-metres-storage
May 19, 2026
Merged

fix(config-sync): store ALTITUDE as bare metres end-to-end#103
d4rken merged 6 commits into
devfrom
fix/altitude-bare-metres-storage

Conversation

@d4rken

@d4rken d4rken commented May 19, 2026

Copy link
Copy Markdown
Member

The website's config-sync wire format expects alt.value as 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 with alt.value must be a number or null. A symmetric round-trip also silently flipped an operator's ft choice 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 new migrate_altitude_to_bare_metres that rewrites already-flashed feeders on the next feed/update.sh. Operator input stays suffix-tolerant; the canonical disk form is bare metres. Range gating moves to post-conversion metres so 20000ft (~6096m) is now accepted and 33000ft (~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

d4rken added 6 commits May 19, 2026 11:36
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.
@d4rken d4rken merged commit 8078a67 into dev May 19, 2026
12 checks passed
@d4rken d4rken deleted the fix/altitude-bare-metres-storage branch May 19, 2026 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant