mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(military): retire unavailable history and keep local trails
This commit is contained in:
1 parent
de2138e84c
commit
5f3d1eaa2f
6 files changed
+40
-34
No files matched your search
@@ -1,5 +1,7 @@
|
|||||||
# God's Eye View Current State
|
# God's Eye View Current State
|
||||||
|
|
||||||
|
The standalone military source no longer requests the unavailable, undocumented ADSB.lol trace endpoint. Tracking retains its locally accumulated trail, and custom sources may still supply optional getTrack history. The old HTTP route validates the identifier then reports 503 history_unavailable without any upstream request, rather than forwarding a misleading 403. This does not restore historical coverage or download bulk daily archives.
|
||||||
|
|
||||||
Shared distance checks use `src/geoDistance.js` with `{ lat, lon }` points and
|
Shared distance checks use `src/geoDistance.js` with `{ lat, lon }` points and
|
||||||
the IUGG mean spherical Earth radius, 6371.0088 km. `greatCircleKm` is
|
the IUGG mean spherical Earth radius, 6371.0088 km. `greatCircleKm` is
|
||||||
canonical; `greatCircleMeters` is its exact metre conversion. Missing,
|
canonical; `greatCircleMeters` is its exact metre conversion. Missing,
|
||||||
|
|||||||
@@ -7,10 +7,9 @@ import { readCappedResponseText } from '../common/http.js';
|
|||||||
* own credit bucket, 4 credits per call on the free tier). OAuth via the
|
* own credit bucket, 4 credits per call on the free tier). OAuth via the
|
||||||
* shared coalesced token. 60s per-icao cache; 404/429 forwarded so the
|
* shared coalesced token. 60s per-icao cache; 404/429 forwarded so the
|
||||||
* client can fall back to its accumulated trail silently.
|
* client can fall back to its accumulated trail silently.
|
||||||
* /api/military/track?hex=<hex> — adsb.lol tar1090 readsb trace
|
* /api/military/track?hex=<hex> — compatibility refusal for the retired,
|
||||||
* (undocumented but live; no browser CORS, hence this proxy). Up to ~24h
|
* undocumented ADSB.lol trace route. The standalone military source uses
|
||||||
* of real history per aircraft. Treat as best-effort; data is ODbL —
|
* locally accumulated trails; provider-supplied history remains optional.
|
||||||
* credit "adsb.lol (ODbL)" in the UI.
|
|
||||||
*/
|
*/
|
||||||
export function trackBackfillProxies() {
|
export function trackBackfillProxies() {
|
||||||
const TRACK_CACHE_MS = 60000;
|
const TRACK_CACHE_MS = 60000;
|
||||||
@@ -107,10 +106,16 @@ export function trackBackfillProxies() {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await proxyJson(
|
res.statusCode = 503;
|
||||||
res,
|
res.setHeader('Content-Type', 'application/json');
|
||||||
`lol:${hex}`,
|
res.setHeader('Cache-Control', 'no-store');
|
||||||
`https://adsb.lol/data/traces/${hex.slice(-2)}/trace_full_${hex}.json`,
|
res.setHeader('Retry-After', '1800');
|
||||||
|
res.end(
|
||||||
|
JSON.stringify({
|
||||||
|
error:
|
||||||
|
'Military history unavailable; locally accumulated trails remain available',
|
||||||
|
code: 'history_unavailable',
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.statusCode = 502;
|
res.statusCode = 502;
|
||||||
|
|||||||
@@ -593,7 +593,7 @@ export function createTracking({
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fire-and-forget adsb.lol readsb trace backfill (PRD F2). Trace points are
|
* Fire-and-forget optional source history backfill (PRD F2). Trace points are
|
||||||
* stride-thinned to the remaining vertex budget, then spliced strictly older
|
* stride-thinned to the remaining vertex budget, then spliced strictly older
|
||||||
* than the oldest seeded fix AHEAD of the locally accumulated fine segment,
|
* than the oldest seeded fix AHEAD of the locally accumulated fine segment,
|
||||||
* capped at TRAIL_MAX_POINTS (newest kept). Any failure (404/timeout/
|
* capped at TRAIL_MAX_POINTS (newest kept). Any failure (404/timeout/
|
||||||
|
|||||||
@@ -214,11 +214,10 @@ test('construction is inert; adapters preserve routes, viewport query, cache epo
|
|||||||
assert.equal(mil.observedAtMs, now - 60000);
|
assert.equal(mil.observedAtMs, now - 60000);
|
||||||
assert.equal(mil.records[0].positionTimeMs, now - 75000);
|
assert.equal(mil.records[0].positionTimeMs, now - 75000);
|
||||||
assert.equal(mil.stale, true);
|
assert.equal(mil.stale, true);
|
||||||
const track = await military.getTrack('abc123');
|
assert.equal(military.getTrack, undefined);
|
||||||
assert.equal(track.complete, false);
|
assert.ok(
|
||||||
assert.equal(track.records[0].observedAtMs, now - 50000);
|
requests.every(({ url }) => !url.startsWith('/api/military/track')),
|
||||||
assert.equal(track.records[0].baroAltitudeM, 304.8);
|
);
|
||||||
assert.equal(track.records[0].ellipsoidAltitudeM, null);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cancellation after slow body parsing rejects even with a transport that ignores abort', async () => {
|
test('cancellation after slow body parsing rejects even with a transport that ignores abort', async () => {
|
||||||
|
|||||||
@@ -159,26 +159,8 @@ export function createMilitarySource({
|
|||||||
status: response.status,
|
status: response.status,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async getTrack(reference, { signal } = {}) {
|
// ADSB.lol does not expose a supported live-history endpoint. Omitting
|
||||||
const { response, payload } = await readResponse(
|
// optional getTrack keeps the tracking layer on its accumulated trail.
|
||||||
fetchImpl,
|
|
||||||
'/api/military/track?hex=' + encodeURIComponent(reference),
|
|
||||||
{ signal },
|
|
||||||
'Military aircraft',
|
|
||||||
);
|
|
||||||
if (!response.ok) throw httpError(response, 'Military aircraft');
|
|
||||||
const baseTimeMs = epoch(payload?.timestamp, 1000);
|
|
||||||
return {
|
|
||||||
records:
|
|
||||||
baseTimeMs == null
|
|
||||||
? []
|
|
||||||
: normalizeAircraftTrack(payload?.trace, {
|
|
||||||
baseTimeMs,
|
|
||||||
readsb: true,
|
|
||||||
}),
|
|
||||||
complete: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -583,3 +583,21 @@ test('track backfill proxy returns 502 on an oversized upstream body and caches
|
|||||||
assert.equal(res2.statusCode, 502);
|
assert.equal(res2.statusCode, 502);
|
||||||
assert.equal(callCount, 1);
|
assert.equal(callCount, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('retired military history refuses without upstream I/O while validating identifiers', async (t) => {
|
||||||
|
t.mock.method(globalThis, 'fetch', async () => {
|
||||||
|
assert.fail('retired history must not contact the upstream');
|
||||||
|
});
|
||||||
|
const route = install(providers.trackBackfillProxies());
|
||||||
|
for (const hex of ['abc123', 'abc456']) {
|
||||||
|
const response = await route('/api/military/track', '?hex=' + hex);
|
||||||
|
assert.equal(response.statusCode, 503);
|
||||||
|
assert.equal(JSON.parse(response.body).code, 'history_unavailable');
|
||||||
|
assert.equal(response.headers['retry-after'], '1800');
|
||||||
|
assert.equal(response.headers['cache-control'], 'no-store');
|
||||||
|
}
|
||||||
|
assert.equal(
|
||||||
|
(await route('/api/military/track', '?hex=invalid')).statusCode,
|
||||||
|
400,
|
||||||
|
);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user