Files
worldmonitor/scripts
Elie Habib 554f5d408c fix(relay): centralize military flights via Redis seed + edge handler (#1263)
* fix(relay): compute theater posture directly instead of pinging Vercel RPC

The relay's theater posture seed loop was pinging the Vercel RPC endpoint
which itself needed WS_RELAY_URL to proxy OpenSky back through the relay —
a circular dependency that resulted in empty theaters.

Now the relay fetches OpenSky directly via its own localhost proxy,
applies military callsign filtering, computes postures for all 9 theaters,
and writes all 3 Redis keys (live/stale/backup) + seed-meta directly.
Wingbits API serves as fallback when OpenSky is unavailable.

* feat(relay): seed military flights to Redis, rewire frontend to read from edge handler

Relay fetches OpenSky every 5 min, filters by ICAO hex ranges (29) and
callsign patterns (83), converts units (m→ft, m/s→kts), and writes to
Redis. Frontend reads pre-filtered data via /api/military-flights edge
handler instead of proxying through OpenSky directly — eliminates
cascading 429 rate limits.

- Add seedMilitaryFlights() with in-flight mutex, 2-region fetch, empty guard
- Add api/military-flights.js edge handler (Redis → stale fallback)
- Rewrite src/services/military-flights.ts to fetchFromRedis()
- Add health.js tracking (STANDALONE_KEYS, SEED_META, CASCADE_GROUPS)
- Theater posture consumes shared flight data (no duplicate OpenSky calls)

* fix(relay): theater posture starvation, aircraftType downgrade, and openskyRelay gate

- Move lastMilFlightsSeedMs after successful posture passthrough so the
  standalone fallback runs when passthrough keeps erroring
- Use f.aircraftType from military seed instead of re-classifying via
  theaterDetectAircraftType (which has no fighter branch)
- Add militaryFlights feature flag with no required secrets; swap gate
  from openskyRelay so desktop users get Redis-backed data without
  legacy OpenSky credentials

* fix(relay): add fighter branch to theaterDetectAircraftType

The standalone theater posture fallback path could not classify fighter
callsigns (BOLT, VIPER, RAPTOR, etc.), causing them to be counted as
unknown and underreporting strike_capable posture levels.

* fix(military-flights): preserve OpenSky direct path for desktop, Redis for web

Desktop (Tauri) cannot reach /api/military-flights (Vercel edge handler).
Restore the original OpenSky direct fetch path for desktop mode while
using the new Redis-backed path for web/cloud. Route based on
isDesktopRuntime() — desktop uses openskyRelay feature gate + direct
OpenSky, web uses militaryFlights feature gate + Redis edge handler.
2026-03-08 14:17:21 +04:00
..