From 92822e2ddcfb3abd4bc69905d752de2d1a738bbb Mon Sep 17 00:00:00 2001 From: mrkmntal Date: Thu, 16 Apr 2026 18:32:53 -0400 Subject: [PATCH] Finish implementation of Hazard list so it can handle when hazards end --- index.mjs | 8 ++++---- server/scripts/modules/hazards.mjs | 7 +++++-- src/hazard-history.mjs | 17 ++++++++++++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/index.mjs b/index.mjs index 89e6a69..929430b 100644 --- a/index.mjs +++ b/index.mjs @@ -307,17 +307,17 @@ if (!process.env?.STATIC) { app.post('/api/hazard-history', async (req, res) => { try { - const { location, hazards } = req.body; + const { location, locationKey, hazards } = req.body; - if (!location || !Array.isArray(hazards)) { + if (!location || !locationKey || !Array.isArray(hazards)) { res.status(400).json({ success: false, - error: 'Missing or invalid location/hazards', + error: 'Missing or invalid location/locationKey/hazards', }); return; } - const history = await updateHistory({ location, hazards }); + const history = await updateHistory({ location, locationKey, hazards }); res.json({ success: true, history, diff --git a/server/scripts/modules/hazards.mjs b/server/scripts/modules/hazards.mjs index 749fe85..e334041 100644 --- a/server/scripts/modules/hazards.mjs +++ b/server/scripts/modules/hazards.mjs @@ -274,9 +274,12 @@ class Hazards extends WeatherDisplay { if (!this.weatherParameters) return; // Format location - const { city, state, country, countryCode } = this.weatherParameters; + const { city, state, country, countryCode, latitude, longitude } = this.weatherParameters; const location = this.formatLocationLabel(city, state, country, countryCode); + // Create stable location key from lat/lon (rounded to 3 decimal places ~111m precision) + const locationKey = `${parseFloat(latitude).toFixed(3)},${parseFloat(longitude).toFixed(3)}`; + // Normalize hazards for the API const hazards = (this.data || []).map((hazard) => ({ id: hazard.id, @@ -291,7 +294,7 @@ class Hazards extends WeatherDisplay { headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify({ location, hazards }), + body: JSON.stringify({ location, locationKey, hazards }), }); } catch (error) { // Silently fail - hazard history is non-critical diff --git a/src/hazard-history.mjs b/src/hazard-history.mjs index e34c585..79c2cb0 100644 --- a/src/hazard-history.mjs +++ b/src/hazard-history.mjs @@ -83,28 +83,34 @@ const formatLocation = (city, state, country, countryCode) => { /** * Update hazard history with current active hazards for a location * @param {Object} payload - Request payload - * @param {string} payload.location - Formatted location label + * @param {string} payload.location - Formatted location label (for display) + * @param {string} payload.locationKey - Stable location key from lat/lon (for matching) * @param {Array} payload.hazards - Array of active hazards * @returns {Array} Updated history */ const updateHistory = async (payload) => { - const { location, hazards = [] } = payload; + const { location, locationKey, hazards = [] } = payload; // Load existing history let history = await loadHistory(); const now = new Date().toISOString(); + // Use locationKey for matching if provided, fall back to location for backward compatibility + const matchKey = locationKey || location; + // Create a set of active hazard keys for this location const activeKeys = new Set(); hazards.forEach((hazard) => { - const key = generateKey(location, hazard.id); + const key = generateKey(matchKey, hazard.id); activeKeys.add(key); }); // Mark previously ongoing hazards for this location as ended if no longer active history = history.map((entry) => { // Only process entries for this location - if (entry.location !== location) return entry; + // Use locationKey for matching if available, fall back to location for backward compatibility + const entryMatchKey = entry.locationKey || entry.location; + if (entryMatchKey !== matchKey) return entry; // If this entry is ongoing but not in the current active set, mark it as ended if (entry.ongoing && !activeKeys.has(entry.key)) { @@ -119,7 +125,7 @@ const updateHistory = async (payload) => { // Add or update active hazards hazards.forEach((hazard) => { - const key = generateKey(location, hazard.id); + const key = generateKey(matchKey, hazard.id); const existingIndex = history.findIndex((entry) => entry.key === key); if (existingIndex >= 0) { @@ -136,6 +142,7 @@ const updateHistory = async (payload) => { history.push({ key, location, + locationKey: matchKey, hazardType: hazard.hazardType, encounteredAt: now, lastSeenAt: now,