mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
Merge remote-tracking branch 'upstream/main' into feature/catalonia-cctv-cameras
# Conflicts: # CHANGELOG.md
This commit is contained in:
commit
49a322519a
29 files changed
+1025
-64
No files matched your search
+23
-1
@@ -1,5 +1,19 @@
|
||||
# God's Eye View Current State
|
||||
|
||||
AIS encodes speed over ground in 0.1-knot units and course over ground in
|
||||
0.1-degree units, reserving the top code of each field for "not available", so
|
||||
those reports arrive as 102.3 knots and 360 degrees. Both are stored as unknown,
|
||||
and vessel cards, the HUD and analyst queries show a missing measurement rather
|
||||
than a reading. Heading keeps its existing separate check for its own sentinel.
|
||||
Genuine readings are unchanged, including a stopped vessel's zero and the
|
||||
highest speed and course the fields can encode.
|
||||
|
||||
Native `<select>` controls declare a dark colour scheme and explicit option
|
||||
colours, so the browser-painted option list matches the panel it drops out of.
|
||||
The scheme is declared on the controls rather than on the document root, so
|
||||
hand-tuned scrollbar and text-input skins are unchanged. Applies to the HUD
|
||||
layout, Scenes, CCTV camera, Radio filter and Draw colour menus.
|
||||
|
||||
Vessel snapshot completeness is separate from freshness. A current snapshot with
|
||||
rejected or duplicate records shows PARTIAL with accepted/received counts; stale
|
||||
or unknown freshness and transport failures retain their warnings. Partial
|
||||
@@ -3543,6 +3557,7 @@ are omitted rather than framing the wrong part of the globe.
|
||||
- Build gate: `npm run build`
|
||||
- Network access: local-only by default (`HOST=localhost` in dev-fresh.sh); LAN is an explicit opt-in via `HOST=0.0.0.0` (launcher prints a key-exposure warning + LAN URL; see SECURITY.md)
|
||||
- OpenSky default mode: OAuth (`OPENSKY_AUTH_MODE=oauth`; `anon` works without credentials)
|
||||
- Setup doctor resolves `OPENSKY_AUTH_MODE` from the environment and dotenv files. Explicit `anon` and OAuth mode without a client pair report keyless anonymous access (rate-limited); a complete OAuth pair retains the existing presence-only capability wording. Basic and auto modes report the selected mode without guessing which credentials runtime will accept. The proxy's auth behavior is unchanged.
|
||||
- Google key expected in Keychain service `google-maps-api` (or `GOOGLE_MAPS_API_KEY`, or `.env`)
|
||||
- OpenSky credentials expected in Keychain service `opensky-network` (or env, or `.env`); `OPENSKY_AUTH_MODE` and `OPENSKY_CREDENTIALS_FILE` read from `.env` too
|
||||
- Optional-key precedence in `dev-fresh.sh` is uniform — explicit shell env, then `.env`, then Keychain: `OPENAI_API_KEY` (Keychain `openai-api`/`api-key` — voice + HUD summary), `AISSTREAM_API_KEY` (`aisstream-api`/`api-key` — live vessels), `CESIUM_ION_TOKEN` (`cesium-ion`/`token` — Bing stacks), `TOMTOM_API_KEY` (`tomtom-api`/`api-key` — live traffic flow), `FIRMS_MAP_KEY` (`firms-map`/`map-key` — live fires), `LL2_API_TOKEN` (`.env` only)
|
||||
@@ -3558,6 +3573,7 @@ are omitted rather than framing the wrong part of the globe.
|
||||
- A cold OpenSky failure uses the current camera subpoint only to request a cached adsb.lol point fallback capped at 250 nm. A fresh OpenSky response or last-good cache wins; a nominally successful worldwide snapshot more than two minutes old prefers viewport-scoped adsb.lol when available, otherwise the stale source is reported honestly. The fallback is visibly source-labeled and is never presented as a worldwide snapshot.
|
||||
- GBFS proxy refuses upstream redirects (`redirect: 'manual'`; any 3xx becomes a 502 and the redirect target is logged server-side only) and enforces its 5 MB response cap while the body streams, cancelling the upstream read past the cap; CCTV health map is bounded.
|
||||
- Proxy error payloads are sanitized (no internal error details returned to clients).
|
||||
- That holds for the OpenAI and CCTV media paths too: `/api/openai/hud-summary` never relays OpenAI's own `error.message`, `/api/realtime/token` passes successful ephemeral-token responses through but answers with a fixed error when minting fails or upstream rejects the request, and a failed CCTV media fetch stores a fixed camera health `message` — `GET /api/cctv/health` serializes that field and the CCTV panel renders it as a status label, so it is a client surface as much as the response body is.
|
||||
- `OPENAI_API_KEY` is server-side only; the browser receives ephemeral Realtime client secrets from `/api/realtime/token`.
|
||||
- `AISSTREAM_API_KEY` is server-side only; the browser reads the same-origin `/api/ais-live` cache.
|
||||
- `/api/google/nearby-places` keeps the Google key out of Places requests issued for voice scene context.
|
||||
@@ -3567,9 +3583,14 @@ are omitted rather than framing the wrong part of the globe.
|
||||
- `/api/route` proxies bounded OSRM route requests for annotation routes, with profile allowlisting, distance caps, response caps, caching, and sanitized "no route found" errors.
|
||||
- Track endpoints: `/api/ais-live/track?mmsi=` (server-accumulated ring buffers; sub-route handled before the rows snapshot), `/api/opensky-track?icao24=` (OAuth, 60s cache, sanitized errors, independent OpenSky credit bucket), `/api/adsblol/trace?hex=` (60s cache, 5MB cap, ODbL attribution required in UI).
|
||||
- Realtime debug logs redact API keys, bearer tokens, client secrets, and image data URLs before writing to disk; request bodies are size-capped.
|
||||
- `/api/realtime/debug-log` enforces an always-on 120-per-client/400-global one-minute limiter (not the opt-in `GEV_RATELIMIT_OPENAI_PER_MIN` bucket the cost-bearing OpenAI routes share), appends asynchronously through a serialized queue, and rotates `realtime-conversations.jsonl` at 32 MB keeping one prior generation, so the sink is bounded at twice that regardless of session length. A malformed record answers 400 and a failed write 500, both with a fixed message.
|
||||
|
||||
## UI/UX Runtime Defaults
|
||||
|
||||
- Trackpad pinch zoom is registered as Cesium's `Ctrl+wheel` camera input.
|
||||
Pixel-mode pinch deltas receive bounded amplification before reaching the
|
||||
canvas; ordinary wheel, line/page-mode and native touch-pinch paths are left
|
||||
unchanged. The application scene owns and removes the relay listener.
|
||||
- Z ladder: panels promote within 100–139 (renormalized on wrap), voice pill 150, toast 200, clean-view exit 300.
|
||||
- Panel POSITION keys are versioned `v8` (`godsEyeView.v8.panelPos.<id>`); collapsed-state keys remain `v6`. The one-time position reset clears stale DISPLAY placements that could overlap the Context rail.
|
||||
- Map Source lives in the bottom Visual Presets tray. The left accordion contains no MAP STACK panel, and the `k` panel token that addressed it is gone from the share registry, so legacy `ui=k...` state takes the ordinary unknown-token skip.
|
||||
@@ -3800,7 +3821,8 @@ easier to meet (detection is now on more often), but does not create it.
|
||||
- Traffic runs in `sim` mode (white dots, hardcoded speeds) unless `TOMTOM_API_KEY`
|
||||
is configured (env or Keychain `tomtom-api`/`api-key`), which enables `live` mode:
|
||||
TomTom flow vector tiles via the budget-governed `/api/tomtom` proxy
|
||||
(`.gev-cache/tomtom/`, 120 s TTL, `TOMTOM_DAILY_TILE_BUDGET` default 40k/day),
|
||||
(`.gev-cache/tomtom/`, 120 s TTL, `TOMTOM_DAILY_TILE_BUDGET` default 6k/day,
|
||||
sized so a 31-day month stays inside TomTom's 200K/month free allowance),
|
||||
decoded client-side (`flowTiles.js`), matched onto Overpass roads
|
||||
(`flowMatch.js`), and rendered as green/amber/red dot color + speed/density
|
||||
scaling (`trafficFlowStyle.js`); closures spawn no dots; unmatched roads stay
|
||||
|
||||
Reference in new issue
Block a user