diff --git a/CHANGELOG.md b/CHANGELOG.md index 21544fa..7c8fb35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## September 8, 2026 + +Launch payloads with missing records now say PAYLOAD DATA UNAVAILABLE. Missing names use Unnamed payload; absent or invalid mass stays unknown instead of appearing as 0 KG. + This changelog records public product changes. For the authoritative description of current runtime behavior, see [`docs/CURRENT-STATE.md`](docs/CURRENT-STATE.md). diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 1f4d861..a14cce4 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -1,5 +1,9 @@ # God's Eye View Current State +## September 8, 2026 + +Launch payloads with missing records now say PAYLOAD DATA UNAVAILABLE. Missing names use Unnamed payload; absent or invalid mass stays unknown instead of appearing as 0 KG. + Updated: August 24, 2026 ## Installations and map-source guidance diff --git a/src/data/rocketLaunches.js b/src/data/rocketLaunches.js index bd9bf79..e8fda9b 100644 --- a/src/data/rocketLaunches.js +++ b/src/data/rocketLaunches.js @@ -2106,13 +2106,15 @@ function normalizePayloadFlights(launch) { const payload = flight.payload || flight; return { id: String(flight.id || payload.id || `payload-${index}`), - name: payload.name || flight.name || 'Undisclosed payload', + name: payload.name || flight.name || 'Unnamed payload', type: payload.type?.name || flight.type?.name || null, manufacturer: payload.manufacturer?.name || null, operator: payload.operator?.name || null, destination: flight.destination || payload.destination || null, amount: Number.isFinite(Number(flight.amount)) ? Number(flight.amount) : 1, - massKg: Number.isFinite(Number(payload.mass)) ? Number(payload.mass) : null, + massKg: (typeof payload.mass === 'number' || (typeof payload.mass === 'string' && payload.mass.trim() !== '')) + && Number.isFinite(Number(payload.mass)) && Number(payload.mass) >= 0 + ? Number(payload.mass) : null, }; }); } @@ -2288,7 +2290,7 @@ function renderMissionPanel() { _missionPanel.querySelector('[data-mission-payloads]').innerHTML = missionTableRows( payloadRows, 3, - 'CLASSIFIED / MULTI-PAYLOAD', + 'PAYLOAD DATA UNAVAILABLE', ); const stageRows = launch.recoveryStages.map((stage) => { const endpoint = stage.endpoint; diff --git a/src/data/rocketLaunches.test.mjs b/src/data/rocketLaunches.test.mjs index dd1ae4c..27d29ff 100644 --- a/src/data/rocketLaunches.test.mjs +++ b/src/data/rocketLaunches.test.mjs @@ -1253,3 +1253,16 @@ test('disable reports a semantic failure while restoring the satellites dependen /could not restore the satellites layer/, ); }); + + +test('missing payload details stay unknown without inventing mass or classification', () => { + for (const [mass, expected] of [[null, null], [undefined, null], ['', null], [' ', null], + [false, null], [-1, null], ['invalid', null], [0, 0], ['125', 125]]) { + const [launch] = normalizeRocketLaunches([{ id: 'mass', pad: { latitude: 1, longitude: 2 }, net: '2026-07-20T10:00:00Z', + payloads: [{ mass }] }], NOW); + assert.equal(launch.payloads[0].massKg, expected); + assert.equal(launch.payloads[0].name, 'Unnamed payload'); + } + const [launch] = normalizeRocketLaunches([{ id: 'missing', pad: { latitude: 1, longitude: 2 }, net: '2026-07-20T10:00:00Z' }], NOW); + assert.deepEqual(launch.payloads, []); +});