fix(map): pin APC (Napa) and STS (Sonoma) observers (#1786) (#1787)

Fixes the map-coordinate gap in #1786.

## Problem

Observers tagged with IATA code **APC** (Napa County) or **STS**
(Charles M. Schulz–Sonoma County) render with no location and never pin
on the map.

## Root cause

`iataCoords` in `cmd/server/routes.go` is a hardcoded `IATA -> lat/lon`
lookup used purely for placing observer/region markers on the map. It
had no entry for APC or STS, so those observers had no coordinates to
render with.

This is **display-only**. Ingestion is not gated on these codes:
`IsObserverIATAAllowed` (`cmd/ingestor/config.go`) short-circuits to
`true` when the observer IATA whitelist is empty — which is the staging
configuration. The reporter''s "packets disappear entirely" symptom is
therefore **not** explained by this code path (likely an upstream
`meshcoretomqtt`/broker topic issue; needs operator `mosquitto_sub`
confirmation per triage).

## Fix

- Add `APC {38.2132, -122.2807}` and `STS {38.509, -122.8128}` to
`iataCoords`, matching the airports'' published coordinates.
- Add a regression test (`TestIataCoordsIncludesNapaAndSonoma`)
asserting both are present with the expected coordinates.

## Verification

- `go test ./cmd/server/` — full package passes (`ok`).
- `go vet ./cmd/server/` — clean.

## Scope note

Checked the repo for other statically-enumerable region codes
(`config.example.json` regions: SJC/SFO/OAK/MRY) — all already covered.
The broader "are other in-use codes missing" question can only be
answered against the live `cfg.Regions` + `db.GetDistinctIATAs()` set,
which is operational, not in-tree.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Erwin Fiten <e.fiten@opteco.be>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
efiten
2026-06-25 11:44:28 +02:00
committed by GitHub
parent 55e203a9c8
commit d437958474
2 changed files with 25 additions and 0 deletions
+2
View File
@@ -2909,6 +2909,8 @@ var iataCoords = map[string]IataCoord{
"LAX": {Lat: 33.9425, Lon: -118.4081},
"SAN": {Lat: 32.7338, Lon: -117.1933},
"SMF": {Lat: 38.6954, Lon: -121.5908},
"APC": {Lat: 38.2132, Lon: -122.2807}, // Napa County
"STS": {Lat: 38.509, Lon: -122.8128}, // Charles M. SchulzSonoma County
"MRY": {Lat: 36.587, Lon: -121.843},
"EUG": {Lat: 44.1246, Lon: -123.2119},
"RDD": {Lat: 40.509, Lon: -122.2934},
+23
View File
@@ -1874,6 +1874,29 @@ func TestConfigRegionsWithCustomRegions(t *testing.T) {
}
}
func TestIataCoordsIncludesNapaAndSonoma(t *testing.T) {
// Issue #1786: observers tagged APC (Napa County) or STS (Charles M.
// SchulzSonoma County) rendered without lat/lon and did not pin on the map
// because iataCoords lacked entries for them.
cases := []struct {
code string
lat, lon float64
}{
{"APC", 38.2132, -122.2807},
{"STS", 38.509, -122.8128},
}
for _, c := range cases {
coord, ok := iataCoords[c.code]
if !ok {
t.Errorf("iataCoords missing %q", c.code)
continue
}
if coord.Lat != c.lat || coord.Lon != c.lon {
t.Errorf("%s = {%v, %v}, want {%v, %v}", c.code, coord.Lat, coord.Lon, c.lat, c.lon)
}
}
}
func TestConfigMapWithCustomDefaults(t *testing.T) {
db := setupTestDB(t)
seedTestData(t, db)